#python #numpy #matrix #transpose
#python #numpy #матрица #транспонировать
Вопрос:
Представьте, что у меня есть матрица 8×8:
[
0 1 1 1 1 1 1 1
0 0 1 1 1 1 1 1
0 0 0 1 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 0 1 1 1
0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
]
Я бы хотел перенести одну строку / столбец из него между 2 точками. Например, если бы я хотел выполнить транспонирование между 2,2 и 6,6 (где 1,1 — крайнее верхнее левое значение), новая матрица должна выглядеть следующим
образом [
0 1 1 1 1 1 1 1
0 0 0 0 0 0 1 1
0 1 0 1 1 0 1 1
0 1 0 0 1 0 1 1
0 1 0 0 0 0 1 1
0 1 1 1 1 0 1 1
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
]
Есть ли хороший способ сделать это? Я пробовал копировать строки в столбцы, а столбцы в строки, но это становится уродливым, когда я начинаю использовать имена переменных в качестве двух точек для переноса между ними
Спасибо
Комментарии:
1. Разрешена ли библиотека numpy?
2. Да, @Keredu, я использую массивы numpy
3. представьте, что вы можете создать матрицу в вашем примере как
x = np.triu(np.ones((8,8), dtype=int), 1)
…4. Привет @Scotty1 — проблема не так проста, как выполнение транспонирования матрицы, потому что, как сказано в названии, я бы хотел, чтобы она выполнялась только в одной строке / столбце…
Ответ №1:
Вы могли бы сделать:
import numpy as np
arr = np.array([
[0, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0]
])
arr[1:6, 1:6] = arr[1:6, 1:6].T
arr[2:5, 2:5] = arr[2:5, 2:5].T
print(arr)
Выходной сигнал
[[0 1 1 1 1 1 1 1]
[0 0 0 0 0 0 1 1]
[0 1 0 1 1 0 1 1]
[0 1 0 0 1 0 1 1]
[0 1 0 0 0 0 1 1]
[0 1 1 1 1 0 1 1]
[0 0 0 0 0 0 0 1]
[0 0 0 0 0 0 0 0]]
Идея состоит в том, чтобы транспонировать подматрицу, а затем еще раз транспонировать внутреннюю часть подматрицы.
Комментарии:
1. звучит расточительно (
O(N^2)
операция, когдаO(N)
она доступна и даже проще для ввода)…
Ответ №2:
Вы можете просто поменять местами столбцы, а затем строки:
x = np.arange(16).reshape((4, 4))
r0, r1 = 0, 1
c0, c1 = 2, 3
x[:, (c0, c1)] = x[:, (c1, c0)]
x[(r0, r1), :] = x[(r1, r0), :]
x
array([[ 4, 5, 7, 6],
[ 0, 1, 3, 2],
[ 8, 9, 11, 10],
[12, 13, 15, 14]])
Специально для вашего примера (и, извините, индексы начинаются с 0, как и предполагала природа):
# setup
x = np.triu(np.ones((8,8), dtype=int), 1)
p0 = 1, 1
p1 = 5, 5
r0, c0, r1, c1 = p0 p1
# operation
x[:, (c0, c1)] = x[:, (c1, c0)]
x[(r0, r1), :] = x[(r1, r0), :]
print(x)
[[0 1 1 1 1 1 1 1]
[0 0 0 0 0 0 1 1]
[0 1 0 1 1 0 1 1]
[0 1 0 0 1 0 1 1]
[0 1 0 0 0 0 1 1]
[0 1 1 1 1 0 1 1]
[0 0 0 0 0 0 0 1]
[0 0 0 0 0 0 0 0]]
Комментарии:
1. Да, именно так я это и сделал. Мне было интересно, есть ли более красивый, более питонический способ сделать это, но если он наиболее эффективен, то я буду придерживаться его. Спасибо
Ответ №3:
import numpy as np
matrix = np.array([[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]])
p1 = (1,1)
p2 = (3,3)
sub_matrix = matrix[p1[0]:p2[0], p1[1]:p2[1]]
matrix[p1[0]:p2[0], p1[1]:p2[1]] = np.transpose(sub_matrix)
print(matrix) # returns [[ 1 2 3 4]
# [ 5 6 10 8]
# [ 9 7 11 12]
# [13 14 15 16]]