I want this
# assume each 2x2 as assigned number on right
[[[False True] # 1
[False False]]
[[False False] # 2
[False True]]
[[ True False] # 3
[False False]]
[[False True] # 4
[False False]]]
to be reshape into
[[[[False True False False]
[False False False True]
[ True False False True]
[False False False False]]]]
as in
[[[[False True | False False] # 1 | 2
[False False | False True] ___ ___
---------- -----------
[ True False | False True] # 3 | 4
[False False | False False]]]]
but I get when using arr.reshape(1,1,4,4)
[[[[False True False False] # 1 flat
[False False False True] # 2 flat
[ True False False False] # 3 flat
[False True False False]]]] # 4 flat
Notice that each 2x2 is flattened. I want numpy to reshape such that 2x2 remains the same while the dimensions before that are adjusted. How do I do it?
EDIT: shape of arr
is m,n,r
and m
could be odd
EDIT2:
Case 9x2x2 into 1x1x6x6
What I have:
[[[False False]
[False True]]
[[False False]
[False True]]
[[ True False]
[False False]]
[[False False]
[False True]]
[[False False]
[ True False]]
[[False False]
[ True False]]
[[False True]
[False False]]
[[False False]
[ True False]]
[[ True False]
[False False]]]
Expected:
[[[[False False | False False | True False]
[False True | False True | False False]
----------- ----------- ----------
[False False | False False | False False]
[False True | True False | True False]
---------- ----------- -----------
[False True | False False | True False]
[False False | True False | False False]]]]
What I got:
[[[[False False False True False False] # 1 flattened; half of 2
[False True True False False False] # rem half of 2; flattened 3
[False False False True False True] # ...
[False False False True False False]
[False False True False False True]
[False False True False False False]]]]
The important piece of the puzzle was that the first axis is a square number and we are splitting it by that square-root number, giving us a 4D
array. If the first axis isn't a squared number, we would need another input argument telling us the number of blocks to be kept along the columns or rows in the final output. After splitting, swap axes 1
and 2
and finally reshape -
m = int(np.rint(np.sqrt(a.shape[0])))
out = a.reshape(m,m,2,2).swapaxes(1,2).reshape(m*2,-1)
Sample run -
1] Input :
In [69]: a
Out[69]:
array([[[False, False],
[False, True]],
[[False, False],
[False, True]],
[[ True, False],
[False, False]],
[[False, False],
[False, True]],
[[False, False],
[ True, False]],
[[False, False],
[ True, False]],
[[False, True],
[False, False]],
[[False, False],
[ True, False]],
[[ True, False],
[False, False]]], dtype=bool)
2] Output :
In [70]: m = int(np.sqrt(a.shape[0]))
In [71]: a.reshape(m,m,2,2).swapaxes(1,2).reshape(m*2,-1)
Out[71]:
array([[False, False, False, False, True, False],
[False, True, False, True, False, False],
[False, False, False, False, False, False],
[False, True, True, False, True, False],
[False, True, False, False, True, False],
[False, False, True, False, False, False]], dtype=bool)
Use einops
for such cases.
In: x
array([[[False, False],
[False, True]],
[[False, False],
[False, True]],
[[ True, False],
[False, False]],
[[False, False],
[False, True]],
[[False, False],
[ True, False]],
[[False, False],
[ True, False]],
[[False, True],
[False, False]],
[[False, False],
[ True, False]],
[[ True, False],
[False, False]]])
In: einops.rearrange(x, '(h w) h2 w2 -> (h h2) (w w2)', h=3)
array([[False, False, False, False, True, False],
[False, True, False, True, False, False],
[False, False, False, False, False, False],
[False, True, True, False, True, False],
[False, True, False, False, True, False],
[False, False, True, False, False, False]])
See einops
docs, basically it allows all kinds of rearrangements being written in explicit way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With