Skip to content Skip to sidebar Skip to footer

How To Obtain An M*n Sub-matrix From A P*q Larger Matrix In Numpy

Came across this while trying to solve a sudoku related question. I need to return all the 3*3 matrices from the larger 9*9 matrix. Is there any direct way of doing this in numpy

Solution 1:

You can achive tiling by adjusting shape and strides of the array:

import numpy as np

x = np.arange(81).reshape(9, 9)

r = x.strides[0]
c = x.strides[1]

y = np.lib.stride_tricks.as_strided(x, shape=(3, 3, 3, 3), strides=(r*3, c*3, r, c))
print(y[1, 1])
# [[30 31 32]#  [39 40 41]#  [48 49 50]]
  1. With shape=(3,3, 3,3) we specify the desired shape of the output: 3x3 sub arrays of size 3x3 each.

  2. With strides= we specify how the memory address changes when going from one element to the next along a dimension. r*3, c*3: the subgrids are spaced in steps of three rows and columns. r, c: the spacing between elements in the subgrid is the same as in the original array.

If you want a simple list of subarrays instead of a 2D arangement, you can do y.reshape(9, 3, 3).

Solution 2:

Not sure if this is the shortest path, but you can get the result with several reshapes and transposes:

import numpy as np

a = np.arange(81).reshape((9, 9))
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]#  [36 37 38 39 40 41 42 43 44]#  [45 46 47 48 49 50 51 52 53]#  [54 55 56 57 58 59 60 61 62]#  [63 64 65 66 67 68 69 70 71]#  [72 73 74 75 76 77 78 79 80]]
b = np.transpose(np.transpose(np.transpose(a.reshape((3, 3, 9)), (1, 0, 2)).reshape((3, -1))).reshape((9, 3, 3)), (0, 2, 1))
print(b[0])
# [[ 0  1  2]#  [ 9 10 11]#  [18 19 20]]print(b[1])
# [[ 3  4  5]#  [12 13 14]#  [21 22 23]]# ...

Post a Comment for "How To Obtain An M*n Sub-matrix From A P*q Larger Matrix In Numpy"