user1658296 - 1 year ago 257
Python Question

# Numpy: rotate sub matrix m of M

If I knew the dimensions of each square submatrix m (2x2), and that the dimensionality of a large square matrix M was evenly divisible by the dimensionality m: M modulo m == 0.

Is there an efficient way to rotate submatrices within the following matrix M:

``````M = array([[ 1.,  2.,  1.,  2.],
[ 3.,  4.,  3.,  4.],
[ 1.,  2.,  1.,  2.],
[ 3.,  4.,  3.,  4.]])
``````

Such that the result is:

``````M* = array([[ 2.,  4.,  2.,  4.],
[ 1.,  3.,  1.,  3.],
[ 2.,  4.,  2.,  4.],
[ 1.,  3.,  1.,  3.]])
``````

In particular, it would be useful to force the use a function like numpy.rot90(), such that other rotations can be achieved e.g.

``````180: rot90(x, 2)
270: rot90(x, 3)
``````

etc.

Here's an approach using `reshape` and `transpose` -

``````m,n = M.shape
out = M.reshape(m//2,2,n//2,2)[...,::-1].transpose(0,3,2,1).reshape(m,n)
``````

Sample run -

``````In [246]: M
Out[246]:
array([[51, 70, 59, 38, 84, 18],
[80, 25, 76, 43, 80, 48],
[92, 98, 46, 14, 65, 47],
[73, 31, 32, 79, 87, 70]])

In [247]: m,n = M.shape

In [248]: M.reshape(m//2,2,n//2,2)[...,::-1].transpose(0,3,2,1).reshape(m,n)
Out[248]:
array([[70, 25, 38, 43, 18, 48],
[51, 80, 59, 76, 84, 80],
[98, 31, 14, 79, 47, 70],
[92, 73, 46, 32, 65, 87]])
``````

If you have to use `np.rot90`, which works only on the first two axes, we need to use `transpose` twice, like so -

``````rot_arr = np.rot90(M.reshape(m//2,2,n//2,2).transpose(0,3,2,1))
out = rot_arr.transpose(1,0,2,3).reshape(m,n)
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download