Issue
I am trying to split a 2D numpy array that is not square into nonoverlapping chunks of smaller 2D numpy arrays. Example - split a 3x4 array into chunks of 2x2:
The array to be split:
[[ 34 15 16 17]
[ 78 98 99 100]
[ 23 78 79 80]]
This should output:
[[34 15]
[78 98]]
[[ 16 17]
[ 99 100]]
So [23 78 79 80]
are dropped because they do not match the 2x2 requirement.
My current code is this:
new_array = np.array([[34,15,16,17], [78,98,99,100], [23,78,79,80]])
window = 2
for x in range(0, new_array.shape[0], window):
for y in range(0, new_array.shape[1], window):
patch_im1 = new_array[x:x+window,y:y+window]
This outputs:
[[34 15]
[78 98]]
[[ 16 17]
[ 99 100]]
[[23 78]]
[[79 80]]
Ideally, I would like to have the chunks stored in a list.
Solution
This should work on any number of dimensions. Let's take an array:
new_array = np.array(range(25)).reshape((5,5))
Output:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])
First calculate the number of last rows/columns which you don't need:
N = 2
rem = np.array(new_array.shape) % N
Output:
array([1, 1])
Then remove the number of rows/columns from the end of your array on each dimension:
for ax, v in enumerate(rem):
if v != 0:
new_array = np.delete(new_array, range(-1, -v-1, -1), axis=ax)
Output:
array([[ 0, 1, 2, 3],
[ 5, 6, 7, 8],
[10, 11, 12, 13],
[15, 16, 17, 18]])
Then use np.split
on each dimension:
arr_list = [new_array]
for ax in range(len(new_array.shape)):
arr_list_list = [np.split(arr, arr.shape[ax] / N, axis=ax) for arr in arr_list]
arr_list = [arr for j in arr_list_list for arr in j]
Output:
[array([[0, 1],
[5, 6]]),
array([[2, 3],
[7, 8]]),
array([[10, 11],
[15, 16]]),
array([[12, 13],
[17, 18]])]
Then transform into a list:
[list(i.reshape(i.size)) for i in arr_list]
Output:
[[0, 1, 5, 6], [2, 3, 7, 8], [10, 11, 15, 16], [12, 13, 17, 18]]
Answered By - AndrzejO
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.