транспонировать / вращать блок матрицы в Python - PullRequest
8 голосов
/ 11 ноября 2011

У меня есть матрица 6x6 в виде списка списков в Python. Матрица разделена на 4 квадратных блока размером 3х3. Я хочу способ сделать транспонирование только 1 блока. Я могу сделать это, используя традиционный метод прохождения каждого элемента и копирования его в другой массив и обратно, и так далее, но я хочу посмотреть, есть ли лучший способ (транспонирование матрицы в python можно выполнить в одну строку, используя почтовый метод)

Например, это представление матрицы и ее блоков

 block 1  block 2
+-------+-------+
| . . . | . . . |
| . . 2 | 1 . . |
| . . . | . . . |
+-------+-------+
| . . . | . . . |
| . . . | . . . |
| . 1 . | . . . |
+-------+-------+
 block 3  block 4

и поворот (3, вправо) должен привести к этому

 block 1  block 2
+-------+-------+
| . . . | . . . |
| . . 2 | 1 . . |
| . . . | . . . |
+-------+-------+
| . . . | . . . |
| 1 . . | . . . |
| . . . | . . . |
+-------+-------+
 block 3  block 4

Я хочу найти метод, который принимает номер блока и вращает только этот блок влево или вправо. Есть ли простой способ сделать это?

Ответы [ 4 ]

5 голосов
/ 11 ноября 2011

Основываясь на идее Свена Марнаха об использовании np.rot90, вот версия, которая вращает квадрант по часовой стрелке (как требуется?).В ключевом шаге

block3[:] = np.rot90(block3.copy(),-1)

a copy() используется с правой стороны (RHS).Без copy(), поскольку значения присваиваются block3, базовые данные, используемые в RHS, также изменяются.Это путает значения, используемые в последующих назначениях.Без copy() несколько одинаковых значений разбросаны по block3.

Я не вижу способа выполнить эту операцию без копии.

import numpy as np
a = np.arange(36).reshape(6, 6)
print(a)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]
#  [24 25 26 27 28 29]
#  [30 31 32 33 34 35]]
block3 = a[3:6, 0:3]

# To rotate counterclockwise
block3[:] = np.rot90(block3.copy())
print(a)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [20 26 32 21 22 23]
#  [19 25 31 27 28 29]
#  [18 24 30 33 34 35]]

# To rotate clockwise
a = np.arange(36).reshape(6, 6)
block3 = a[3:6, 0:3]
block3[:] = np.rot90(block3.copy(),-1)
print(a)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [30 24 18 21 22 23]
#  [31 25 19 27 28 29]
#  [32 26 20 33 34 35]]
4 голосов
/ 11 ноября 2011

Для чего это стоит, вот как это просто в NumPy:

>>> a = numpy.arange(36).reshape(6, 6)
>>> a
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23],
       [24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35]])
>>> block3 = a[3:6, 0:3]
>>> block3[:] = numpy.rot90(block3, 1).copy()
>>> a
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [20, 26, 32, 21, 22, 23],
       [26, 25, 31, 27, 28, 29],
       [20, 26, 20, 33, 34, 35]])
0 голосов
/ 11 ноября 2011

Вот метод для поворота «блока» из предоставленной вами матрицы:

matrix = [[0,1,2],[3,4,5],[6,7,8]]

def rotate(m, right):
    rm = []
    for i in range(0,len(m)):
        if right:
            rm.append([row[i] for row in reversed(m)])
        else:
            rm.append([row[i] for row in m])
    return rm

right является Bool
Это вернет list of lists

Вы также можете использовать:

def rotate(m, right):
    if right:
        return list(zip(*reversed(m)))
    else:
        return list(zip(*m))

но это вернет list of tuples


EDIT:

Если речь идет о матрице типа:

matrix = [[[1,2,3],[4,5,6],[7,8,9]], # block 1
          [[1,2,3],[4,5,6],[7,8,9]], # block 2
          [[1,2,3],[4,5,6],[7,8,9]], # block 3
          [[1,2,3],[4,5,6],[7,8,9]]  # block 4
         ]

вы бы получили доступ к блоку 3, используя matrix[2]

, поэтому функция поворота будет использоваться следующим образом:
rotate(matrix[2], True) #rotate block 3, right

0 голосов
/ 11 ноября 2011

Было бы решением определить матрицу как словарь блоков, а блок как список списков? В вашем примере (замените transpose () на функцию, которую вы используете для транспонирования):

Matrix={1:block1,2:block2,3:block3,4:block4}
block3=transpose(block3)
Matrix[3]=block3
...