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 a way to take a transpose of only 1 block. I can do it using the traditional method of going through each element and copying it into another array and back and so on but I want to see if there is a better way, (transposing a matrix in python can be done in one line using the zip method)
for eg this is the representation of the matrix and its blocks
block 1 block 2
+-------+-------+
| . . . | . . . |
| . . 2 | 1 . . |
| . . . | . . . |
+-------+-------+
| . . . | . . . |
| . . . | . . . |
| . 1 . | . . . |
+-------+-------+
block 3 block 4
and rotate(3, right) should result in this
block 1 block 2
+-------+-------+
| . . . | . . . |
| . . 2 | 1 . . |
| . . . | . . . |
+-------+-------+
| . . . | . . . |
| 1 . . | . . . |
| . . . | . . . |
+-------+-------+
block 3 block 4
I want to find a method that takes in a block number and rotates only that block left or right. Is there any easy way to do it?
Building on Sven Marnach's idea to use np.rot90, here is a version which rotates the quadrant clockwise (as requested?). In the key step
block3[:] = np.rot90(block3.copy(),-1)
a copy() is used on the right-hand side (RHS). Without the copy(), as values are assigned to block3, the underlying data used on the RHS is also changed. This muddles the values used in subsquent assignments. Without the copy(), multiple same values are spread about block3.
I don't see a way to do 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]]
For what it's worth, here's how simple this in 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]])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With