4

Given the following input numpy array of shape(n**2 * m, m), with n=2 and m=5 :

A = np.array([[  71.87,   47.8 ,   24.84,   25.31,   15.43],
              [ 174.8 ,  131.84,   57.57,   76.53,   48.5 ],
              [   4.4 ,    2.  ,    1.6 ,    1.  ,    0.  ],
              [  28.71,   15.  ,   10.5 ,    4.17,    2.52],
              [ 222.8 ,  123.59,    7.72,  -39.33,    4.65],
              [ 156.84,  138.17,   21.75,   80.86,   44.55],
              [  89.5 ,  133.01, -114.69,    1.  , -167.7 ],
              [  21.25,   19.57, -177.65,   57.38, -119.75],
              [ 162.33,    7.72,  -51.72,  117.31,  -87.87],
              [  77.57,   26.75,   36.64,    6.99,   25.97],
              [ 276.6 ,  275.31, -128.61,  105.7 ,  -86.5 ],
              [ 135.5 ,  232.67,    9.15,   -5.25,  -48.62],
              [ 325.31,  238.17,  -32.69,   41.55,    3.32],
              [ 126.53,  118.36,  -13.64,  104.64,    7.66],
              [ 522.25,  176.  , -338.05,  265.95, -411.87],
              [  16.67,  116.75, -255.25,  109.61, -397.18],
              [  15.43,  267.15,  159.63,    3.32,   30.31],
              [  48.5 ,   83.93,   63.47,   17.66,   70.16],
              [ 321.25,  213.55,    1.  ,  368.13, -261.55],
              [ 107.52,    5.25,  -89.25,  423.44,  -80.89]])

How one could reshape and permute axes of A in order to obtain the following output B of shape (n*m, n*m) ?

B = np.array([[  71.87,  174.8 ,  222.8 ,  156.84,  162.33,   77.57,  325.31,  126.53,   15.43,   48.5 ],
              [   4.4 ,   28.71,   89.5 ,   21.25,  276.6 ,  135.5 ,  522.25,   16.67,  321.25,  107.52],
              [  47.8 ,  131.84,  123.59,  138.17,    7.72,   26.75,  238.17,  118.36,  267.15,   83.93],
              [   2.  ,   15.  ,  133.01,   19.57,  275.31,  232.67,  176.  ,  116.75,  213.55,    5.25],
              [  24.84,   57.57,    7.72,   21.75,  -51.72,   36.64,  -32.69,  -13.64,  159.63,   63.47],
              [   1.6 ,   10.5 , -114.69, -177.65, -128.61,    9.15, -338.05, -255.25,    1.  ,  -89.25],
              [  25.31,   76.53,  -39.33,   80.86,  117.31,    6.99,   41.55,  104.64,    3.32,   17.66],
              [   1.  ,    4.17,    1.  ,   57.38,  105.7 ,   -5.25,  265.95,  109.61,  368.13,  423.44],
              [  15.43,   48.5 ,    4.65,   44.55,  -87.87,   25.97,    3.32,    7.66,   30.31,   70.16],
              [   0.  ,    2.52, -167.7 , -119.75,  -86.5 ,  -48.62, -411.87, -397.18, -261.55,  -80.89]])

This transformation is easily done using for loops but as I need to be efficient here, I am looking for a proper reshape-based solution with a bit of clarification on the logic behind it.

Any help would be greatly appreciated.

3
  • 1
    Your values change, for example 162.33 to 162.34 index [0,4] in your expected output. What is the logic behind this? Commented Dec 3, 2020 at 22:39
  • could you please provide us with for loop answer. It is not obvious how you reshaped the original one to last one Commented Dec 3, 2020 at 22:39
  • @MichaelSzczesny, sorry for that, the values came from different methods and may not be so close because of the specified precision in order to obtain small matrices for this question and np.set_printoptions kwargs. Commented Dec 3, 2020 at 22:44

2 Answers 2

2

It took a bit of squinting at your data to find out that, in the output, the columns of A have been chunked by blocks of n*n and tiled into nxn squares. So, for example, the B[:2, :2] has the values of A[:4, 0].

So, the key is to try to do put those blocks into contiguous dimensions, then use a transpose of the appropriate axes, before a final reshape.

Long story short:

B = np.reshape(np.reshape(A.T, (m, m, n, n)).transpose(0, 2, 1, 3), (n*m, n*m))
Sign up to request clarification or add additional context in comments.

Comments

1

You can reshape blockwise with the usual reshape, swapaxes, reshape. @divakar posted a detailed explanation.

A.T.reshape(5,5,2,2).swapaxes(1,2).reshape(10,-1)

Out:

array([[  71.87,  174.8 ,  222.8 ,  156.84,  162.33,   77.57,  325.31, 126.53,    15.43,   48.5 ],
       [   4.4 ,   28.71,   89.5 ,   21.25,  276.6 ,  135.5 ,  522.25,  16.67,   321.25,  107.52],
       [  47.8 ,  131.84,  123.59,  138.17,    7.72,   26.75,  238.17, 118.36,   267.15,   83.93],
       [   2.  ,   15.  ,  133.01,   19.57,  275.31,  232.67,  176.  , 116.75,   213.55,    5.25],
       [  24.84,   57.57,    7.72,   21.75,  -51.72,   36.64,  -32.69, -13.64,   159.63,   63.47],
       [   1.6 ,   10.5 , -114.69, -177.65, -128.61,    9.15, -338.05, -255.25,    1.  ,  -89.25],
       [  25.31,   76.53,  -39.33,   80.86,  117.31,    6.99,   41.55,  104.64,    3.32,   17.66],
       [   1.  ,    4.17,    1.  ,   57.38,  105.7 ,   -5.25,  265.95,  109.61,  368.13,  423.44],
       [  15.43,   48.5 ,    4.65,   44.55,  -87.87,   25.97,    3.32,    7.66,   30.31,   70.16],
       [   0.  ,    2.52, -167.7 , -119.75,  -86.5 ,  -48.62, -411.87, -397.18, -261.55,  -80.89]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.