0

I have an array of 20 ndarray objects in the shape (640, 480) which corresponds to image frames that I am working with.

I'd like to "partition" each of these ndarray objects into 8 smaller "chunks", each with the shape (160, 240) but seem to be not getting the proper results. I'm currently trying this:

frames = [np.zeros((640, 480)) for _ in range(20)] # 20 "image frames"
res = [frame.reshape((240, 160, 8)) for frame in frames]

And what res ends up equaling is an array of 20 ndarray objects with the shape (160, 240, 8), whereas instead I would like res to equal an array of subarrays, where each subarray contains 8 ndarray objects of shape (160, 240).

Joey Orlando
  • 1,408
  • 2
  • 17
  • 33
  • 1
    I don't really get it. Are you unhappy about `res` being a len-20-list of numpy-arrays with shape (8,160,240) instead of being a numpy array itself with shape (20,8,160,240)? Why then don't you add `res = np.array(res)`? – SpghttCd Jul 11 '18 at 15:31
  • You have to make the distinction between a Python list and a NumPy array here, and where (and why) you want to use Python lists. – miradulo Jul 11 '18 at 15:46
  • Is `res[0][:,:,0]` a correct chunk? The `[0]` selects an array from the list. `[:,:,0]` selects a chunk from the `frame`. If so `np.array(res)` will be a 4d array that would allow similar selection. We could also tranpose axes to the size 8 dimension is that the start. – hpaulj Jul 11 '18 at 16:22

2 Answers2

1

I believe what you want to do is split your 2D arrays into chunks. This old answer might help with your query: Slice 2d array into smaller 2d arrays

Amit
  • 482
  • 4
  • 10
1

The already mentioned post Slice 2d array into smaller 2d arrays was indeed a good solution then, but nowadays I think this can be done easier, because numpy has now splitting functions itself, so your task can be a one liner:

chunks = [np.vsplit(sub, nrows) for sub in np.hsplit(big_array, ncols)]
# with big_array, nrows and ncols replaced by variables/values relevant for you

There is just a little difference: here nrows and ncols are the number of blocks in each direction, not the number of rows/columns within each block.

And now for comparison the same example array:

c = np.arange(24).reshape((4,6))
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]])

c_blocked  = [np.vsplit(sub, 2) for sub in np.hsplit(c, 2)]
[[array([[0, 1, 2],
         [6, 7, 8]]), array([[12, 13, 14],
         [18, 19, 20]])], [array([[ 3,  4,  5],
         [ 9, 10, 11]]), array([[15, 16, 17],
         [21, 22, 23]])]]

c_blocked[0][0]
array([[0, 1, 2],
       [6, 7, 8]])

c_blocked[0][1]
array([[12, 13, 14],
       [18, 19, 20]])

c_blocked[1][0]
array([[ 3,  4,  5],
       [ 9, 10, 11]])

c_blocked[1][1]
array([[15, 16, 17],
       [21, 22, 23]])
SpghttCd
  • 10,510
  • 2
  • 20
  • 25