Home > OS >  numpy.block issue with reshaping
numpy.block issue with reshaping

Time:04-13

I have been stuck on this problem for a while now and would really appreciate if someone could give any ideas?

I have a numpy array, say, A, of shape: (3, 3, 3, 3). I want to basically make it a 2D array, B of shape: (9, 9) while preserving the contents of A in a natural block order, i.e. A[0][0][:][:] is basically a 3 x 3 sub-matrix, which should also appear in the top-left portion of B. Similarly, A[2][2][:][:] should appear in the bottom-right portion of B and so on. I have attached the example, to clarify. original array, A:

array([[[[ 0,  0,  0],
         [ 0,  0,  0],
         [ 0,  0,  0]],

        [[ 1,  1,  1],
         [ 1,  1,  1],
         [ 1,  1,  1]],

        [[ 2,  2,  2],
         [ 2,  2,  2],
         [ 2,  2,  2]]],


       [[[-1, -1, -1],
         [-1, -1, -1],
         [-1, -1, -1]],

        [[ 0,  0,  0],
         [ 0,  0,  0],
         [ 0,  0,  0]],

        [[ 1,  1,  1],
         [ 1,  1,  1],
         [ 1,  1,  1]]],


       [[[-2, -2, -2],
         [-2, -2, -2],
         [-2, -2, -2]],

        [[-1, -1, -1],
         [-1, -1, -1],
         [-1, -1, -1]],

        [[ 0,  0,  0],
         [ 0,  0,  0],
         [ 0,  0,  0]]]])

and desired array, B:

array([[ 0,  0,  0,  1,  1,  1,  2,  2,  2],
       [ 0,  0,  0,  1,  1,  1,  2,  2,  2],
       [ 0,  0,  0,  1,  1,  1,  2,  2,  2],
       [-1, -1, -1,  0,  0,  0,  1,  1,  1],
       [-1, -1, -1,  0,  0,  0,  1,  1,  1],
       [-1, -1, -1,  0,  0,  0,  1,  1,  1],
       [-2, -2, -2, -1, -1, -1,  0,  0,  0],
       [-2, -2, -2, -1, -1, -1,  0,  0,  0],
       [-2, -2, -2, -1, -1, -1,  0,  0,  0]])

CodePudding user response:

You input is ambiguous. I can reproduce it using:

a = np.repeat(np.array([0,1,2,-1,0,1,-2,-1,0]), 9).reshape(3,3,3,3)

And then, swapping axes and reshaping gives:

a.swapaxes(1,2).reshape(9,9)

array([[ 0,  0,  0,  1,  1,  1,  2,  2,  2],
       [ 0,  0,  0,  1,  1,  1,  2,  2,  2],
       [ 0,  0,  0,  1,  1,  1,  2,  2,  2],
       [-1, -1, -1,  0,  0,  0,  1,  1,  1],
       [-1, -1, -1,  0,  0,  0,  1,  1,  1],
       [-1, -1, -1,  0,  0,  0,  1,  1,  1],
       [-2, -2, -2, -1, -1, -1,  0,  0,  0],
       [-2, -2, -2, -1, -1, -1,  0,  0,  0],
       [-2, -2, -2, -1, -1, -1,  0,  0,  0]])

But this could be incorrect depending on how you want each 3x3 block to behave when becoming another 3x3 block.

Given a range input 0->80 (a = np.arange(3**4).reshape(3,3,3,3)):

array([[[[ 0,  1,  2],
         [ 3,  4,  5],
         [ 6,  7,  8]],

        [[ 9, 10, 11],
         [12, 13, 14],
         [15, 16, 17]],
...

This would give:

array([[ 0,  1,  2,  9, 10, 11, 18, 19, 20],
       [ 3,  4,  5, 12, 13, 14, 21, 22, 23],
       [ 6,  7,  8, 15, 16, 17, 24, 25, 26],
       [27, 28, 29, 36, 37, 38, 45, 46, 47],
       [30, 31, 32, 39, 40, 41, 48, 49, 50],
       [33, 34, 35, 42, 43, 44, 51, 52, 53],
       [54, 55, 56, 63, 64, 65, 72, 73, 74],
       [57, 58, 59, 66, 67, 68, 75, 76, 77],
       [60, 61, 62, 69, 70, 71, 78, 79, 80]])

Is this what you want?

  • Related