在Python中转置/旋转矩阵块

8 投票
4 回答
5498 浏览
提问于 2025-04-17 06:04

我在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]]

撰写回答