在Python中转置/旋转矩阵块
我在Python中有一个6x6的矩阵,它是一个列表的列表。这个矩阵被分成了4个3x3的方块。我想找到一种方法,只对其中一个方块进行转置。虽然我可以用传统的方法,逐个元素地复制到另一个数组中,然后再复制回来,但我想看看有没有更好的方法(在Python中,转置一个矩阵可以用zip方法一行代码完成)。
例如,这里是矩阵及其方块的表示:
block 1 block 2
+-------+-------+
| . . . | . . . |
| . . 2 | 1 . . |
| . . . | . . . |
+-------+-------+
| . . . | . . . |
| . . . | . . . |
| . 1 . | . . . |
+-------+-------+
block 3 block 4
而rotate(3, right)应该得到这个结果:
block 1 block 2
+-------+-------+
| . . . | . . . |
| . . 2 | 1 . . |
| . . . | . . . |
+-------+-------+
| . . . | . . . |
| 1 . . | . . . |
| . . . | . . . |
+-------+-------+
block 3 block 4
我想找一种方法,输入一个方块的编号,只对那个方块进行左右旋转。有简单的方法吗?
4 个回答
0
有没有一种方法可以把矩阵定义成一个块的字典,而把一个块定义成一个列表的列表呢?在你的例子中(把transpose()替换成你用来转置的函数):
Matrix={1:block1,2:block2,3:block3,4:block4}
block3=transpose(block3)
Matrix[3]=block3
4
这段话的意思是,接下来要分享的是在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]])
5
在Sven Marnach的想法基础上,使用了np.rot90
,这里有一个版本可以顺时针旋转象限(这是你想要的吗?)。在关键步骤中
block3[:] = np.rot90(block3.copy(),-1)
右侧使用了copy()
。如果不使用copy()
,当值被赋给block3
时,右侧使用的数据也会被改变。这会导致后续赋值时的值变得混乱。如果没有copy()
,block3
中会出现多个相同的值。
我觉得没有copy()
就无法完成这个操作。
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]]