Transpose / rotate matrix block in python

I have a 6x6 matrix as a list of lists in python. The matrix is ​​divided into 4 square blocks of size 3x3. I want to transpose only one block. I can do this using the traditional method of traversing each element and copying it to another array and vice versa, etc., but I want to see if there is a better way (matrix transfer in python can be done on one line using zip)

for example, this is a representation of the matrix and its blocks

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

and turning (3, right) should lead to this

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

I want to find a method that takes a block number and rotates only that block left or right. Is there an easy way to do this?

+8
python matrix transpose
source share
4 answers

Based on the idea of ​​Sven Marnach to use np.rot90 , here is a version that rotates the quadrant clockwise (on request?). At the key step

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

a copy() used on the right side (RHS). Without copy() , since the values ​​are assigned to block3 , the underlying data used in RHS also changes. This confuses the values ​​used in subsequence assignments. Without copy() several identical values ​​apply approximately to block3 .

I see no way to perform this operation without a 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]] 
+5
source share

For what it's worth, here's how simple it is in 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]]) 
+4
source share

Would it be a decision to define a matrix as a dictionary of blocks and a block as a list of lists? In your example (replace the transpose () with the function that you use to transpose):

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

Here is a way to rotate the “Block” from the matrix you provided:

 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 is Bool
This will return a list of lists

you can also use:

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

but it will return a list of tuples


EDIT:

If we are talking about a matrix like:

 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 ] 

you will access block 3 with matrix[2]

therefore, the rotate function will be used as:
rotate(matrix[2], True) #rotate block 3, right

0
source share

All Articles