2011-11-10 753 views
8

我有一个6x6矩阵作为python中的列表列表。该矩阵被分成4个大小为3×3的方块。我想要一种只有1块的转置方式。我可以使用传统的方法来遍历每个元素并将其复制到另一个数组中并返回等等,但是我想查看是否有更好的方法,(在Python中转换矩阵可以在一行中使用拉链方法)在python中转置/旋转矩阵块

为例如这是

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

和旋转(3矩阵的表示和它的块,右)应导致此

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

我想找到一种方法只需输入一个程序段号并只向左或向右旋转该程序段。有没有简单的方法来做到这一点?

+1

操作是否应该到位? –

+0

是的,它需要到位,或至少,结果需要写回原始矩阵 – randomThought

回答

5

大厦斯文Marnach的使用np.rot90想法,这里是旋转象限版本顺时针(按要求?)。在关键步骤

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

一个copy()被用在右侧(右轴)。如果没有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]] 
0

这是一个解决方案,将矩阵定义为块的字典并将块定义为列表的列表? 在您的例子(您使用移调它取代的功能转置()):

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

不是真的,因为我需要执行其他矩阵操作,这种结构将不允许或将会过于复杂。 – randomThought

0

这里是从基体转动“块”的方法您提供:

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 

rightBool
这将返回一个list of lists

你也可以使用:

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

但这将返回list of tuples


编辑:使用matrix[2]

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:如果我们是在谈论类型的矩阵

所以旋转的乐趣ction将用于类似:
rotate(matrix[2], True) #rotate block 3, right

+0

是的。整个矩阵列表的数字列表。 – randomThought

+0

这个例子中列出了它的矩阵列表,如果它列出了数字列表,你可以通过旋转(矩阵[2],True/False)来选择第三个数据块' – Serdalis

+0

但你如何提取只有块传递给函数? – randomThought

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]]) 
+0

+1。但是请注意,在原地复制右侧的'block3 [:]'具有不希望的副作用 - 当新的值被分配给'block3'时,右侧的基础值也会被覆盖,在结果中留下相同值的多个副本。 – unutbu

+0

@unutbu:谢谢你指出这一点。我甚至没有看结果 - 我确定'numpy.rot90()'返回一个新的数组,而不是一个视图。 –