Reshaping/Combining several sub-matrices to one matrix in multi-dimensional space

醉酒当歌 提交于 2019-12-10 18:48:46

问题


I have a 5D binary array 'a' of size (2, 2, 4, 2, 2). The structure looks like this, for example:

a[0,0]:
[[[ 0.  1.]
  [ 0.  0.]]

 [[ 0.  0.]
  [ 0.  1.]]

 [[ 0.  0.]
  [ 0.  1.]]

 [[ 0.  0.]
  [ 1.  0.]]]

What I want to do is to make a (2,2,4,4) matrix that combines the 2x2 matrices in the last two axis, but in a squared structure.

The result should look like this:

result[0,0]:
[[0. 1. 0. 0.]
 [0. 0. 0. 1.]
 [0. 0. 0. 0.]
 [0. 1. 1. 0.]]

I hope this is clear enough. If I put the brackets of original matrices in results, it looks like this:

result[0,0]:
[[[0. 1. [0. 0.]
 [0. 0.] 0. 1.]]
 [[0. 0. [0. 0.]
 [0. 1.] 1. 0.]]]

回答1:


It seems you are breaking the third axis from (4) into (2,2) and bringing in the first half of the split axes to the second last axes position. So, there are two ways to achieve such an output using np.reshape and np.transpose, like so -

out = a.reshape(2,2,2,2,2,2).transpose(0,1,3,4,2,5).reshape(2,2,4,4)

out = a.reshape(2,2,2,-1,2).transpose(0,1,3,2,4).reshape(2,2,4,4)

Sample run -

In [69]: a[0][0]
Out[69]: 
array([[[49, 91],
        [10, 32]],

       [[71, 27],
        [50, 64]],

       [[ 9, 41],
        [73, 52]],

       [[54, 85],
        [53, 36]]])

In [70]: out1 = a.reshape(2,2,2,2,2,2).transpose(0,1,3,4,2,5).reshape(2,2,4,4)

In [71]: out2 = a.reshape(2,2,2,-1,2).transpose(0,1,3,2,4).reshape(2,2,4,4)

In [72]: out1[0][0]
Out[72]: 
array([[49, 91,  9, 41],
       [10, 32, 73, 52],
       [71, 27, 54, 85],
       [50, 64, 53, 36]])

In [73]: out2[0][0]
Out[73]: 
array([[49, 91,  9, 41],
       [10, 32, 73, 52],
       [71, 27, 54, 85],
       [50, 64, 53, 36]])



回答2:


First, it is better to index your array like a[0,0] or a[0,0,...] or a[0,0,:,:].

Does a.reshape(2,2, 4,4) do what you want? That retains all values, but reshapes the inner most (2,2) arrays into (4,) arrays.

Looking more closely it looks like you want to reorder values in the inner arrays. That is not entirely obvious from your description. I had to carefully match up values between the displays. In particular it's only 2 of the subarrays that are unabiguous:

[[ 0.  0.]
  [ 0.  1.]]

 [[ 0.  0.]
  [ 1.  0.]]]

[0. 0. 0. 0.]
 [0. 1. 1. 0.]]

What we will need to do is transpose the last 2 axes before reshaping.

This might do the trick:

a.transpose(0,1,2,4,3).reshape(2,2,4,4)

It works with np.ones((2,2,4,2,2)), but I haven't tested it with numbers that duplicate your question - because you did not give a test case that can be cut-n-pasted.


oops - looks like Divakar got it right. We need to break up the 4 dimension into 2,2, and perform the transpose across dimensions.

In [290]: a=np.array([[[0,1],[0,0]],[[0,0],[0,1]],[[0,0],[0,1]],[[0,0],[1,0]]])
In [291]: a
Out[291]: 
array([[[0, 1],
        [0, 0]],

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

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

       [[0, 0],
        [1, 0]]])
In [292]: a.reshape(2,2,2,2).transpose(0,2,1,3).reshape(4,4)
Out[292]: 
array([[0, 1, 0, 0],
       [0, 0, 0, 1],
       [0, 0, 0, 0],
       [0, 1, 1, 0]])

Here's a clearer example:

In [303]: a=np.arange((4*2*2)).reshape(4,2,2)
In [304]: a.reshape(2,2,2,2).transpose(0,2,1,3).reshape(4,4)
Out[304]: 
array([[ 0,  1,  4,  5],
       [ 2,  3,  6,  7],
       [ 8,  9, 12, 13],
       [10, 11, 14, 15]])

It would be even better if each of the dimensions was different, so there'd even less ambiguity as to which ones are being combined.

In [308]: a=np.arange((6*5*7)).reshape(6,5,7)
In [309]: a.reshape(2,3,5,7).transpose(0,2,1,3).reshape(10,21)


来源:https://stackoverflow.com/questions/34606602/reshaping-combining-several-sub-matrices-to-one-matrix-in-multi-dimensional-spac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!