I would like to reshape an array in python (a numpy array at first) in a way that each element at the first index becomes a square/quadrant in that array, not the regular reshaping that takes all elements in a row.
It's a reshape + reorganize.
And of course, the fastest/better way of doing it :)
(Prefer python 3.5)
Using an array shaped in rows,columns,channels.
As an example, I've created this array, which you can interpret as an image. I've added values to it so we can clearly see which row, column and channel every element belongs to:
import numpy as np
X = np.zeros((8,6,3)) #8 rows, 6 columns, 3 channels (imagine RGB channels)
for i in range(3):
X[:,:,i] += i+1 #the last digit in the array elements are channels
for i in range(6):
X[:,i,:] += 10*(i+1) #the second digit in elements are columns
for i in range(8):
X[i,:,:] += 100*(i+1) #the first digit in elements are rows
Printing this array shows:
[[[ 111. 112. 113.]
[ 121. 122. 123.]
[ 131. 132. 133.]
[ 141. 142. 143.]
[ 151. 152. 153.]
[ 161. 162. 163.]]
[[ 211. 212. 213.]
[ 221. 222. 223.]
[ 231. 232. 233.]
[ 241. 242. 243.]
[ 251. 252. 253.]
[ 261. 262. 263.]]
...
- So, it's clear that the first index is grouped as image rows (the first digit is constant in every larger group)
- The second index are columns, they change in each smaller group inside the big ones
- The last index are channels, they change individually, element for element inside the smaller groups.
Regular reshape doesn't satisfy my conditions
Now, suppose I want to reshape this array in 12 squares, each square being 2 x 2 (two rows and two columns), keeping the channels as the last dimension.
If I simply print(X.reshape(12,2,2,3)), I get this:
[
[
[
[ 111. 112. 113.]
[ 121. 122. 123.]
]
[
[ 131. 132. 133.]
[ 141. 142. 143.]
]
]
[
[
[ 151. 152. 153.]
[ 161. 162. 163.]
]
[
[ 211. 212. 213.]
[ 221. 222. 223.]
]
]
....
The first index groups elements all of the first row (they start with 1). So, it's not taking "squares" in the image, but grouping things in a straight row. It never takes elements from row 2 until all columns in row 1 are taken.
Expected result
How can I reshape it properly and efficiently so the first index returns squares (2 rows, 2 columns), like this:
[
[
[
[ 111. 112. 113.]
[ 121. 122. 123.]
]
[
[ 211. 212. 213.]
[ 221. 222. 223.]
]
]
[
[
[ 131. 132. 133.]
[ 141. 142. 143.]
]
[
[ 231. 232. 233.]
[ 241. 242. 243.]
]
]
[
[
[ 151. 152. 153.]
[ 161. 162. 163.]
]
[
[ 251. 252. 253.]
[ 261. 262. 263.]
]
]
[
[
[ 311. 312. 313.]
[ 321. 322. 323.]
]
[
[ 411. 412. 413.]
[ 421. 422. 423.]
]
]
....