Say I have an array that looks like
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, 25, 26, 27, 28, 29, 30, 31],
[32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47],
[48, 49, 50, 51, 52, 53, 54, 55],
[56, 57, 58, 59, 60, 61, 62, 63]])
And I wanted to extract the following array:
array([[ 0, 1, 4, 5],
[ 8, 9, 12, 13],
[32, 33, 36, 37],
[40, 41, 44, 45]])
Essentially it's the top-left 2x2 block in every 4x4 macro-block. I saw this example in 1D, but couldn't figure out the 2D case. Another way I can think of is:
h, w = full.shape
X, Y = np.meshgrid(np.arange(w), np.arange(h))
tl = full[(X%4<2) & (Y%4<2)].reshape((h//2,-1))
But I wonder if there's a cleaner way of doing this.
CodePudding user response:
Here's one way you could do it:
In [73]: a
Out[73]:
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, 25, 26, 27, 28, 29, 30, 31],
[32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47],
[48, 49, 50, 51, 52, 53, 54, 55],
[56, 57, 58, 59, 60, 61, 62, 63]])
In [74]: nr, nc = [s // 2 for s in a.shape] # Shape of the new array
In [75]: b = a.reshape((nr, 2, nc, 2))[::2, :, ::2, :].reshape(nr, nc)
In [76]: b
Out[76]:
array([[ 0, 1, 4, 5],
[ 8, 9, 12, 13],
[32, 33, 36, 37],
[40, 41, 44, 45]])
CodePudding user response:
By specifying the index array, so if a.shape[0] % 2 == 0
(even number):
Note: these methods can handle not only when a.shape[0] % 4 == 0
, but also a.shape[0] % 2 == 0
(for all even numbers).
First method:
using advance indexing:
w = 2
ind = np.arange(a.shape[1]).reshape(-1, w)[::2].ravel() # [0 1 4 5]
b = a[ind[:, None], ind[None, :]]
Second method:
by np.delete
:
w = 2
ind = np.arange(a.shape[1]).reshape(-1, w)[1::2].ravel() # [2 3 6 7]
b = np.delete(a, ind, axis=0)
b = np.delete(b, ind, axis=1)
Third method:
by splitting and stacking as:
b = np.asarray(np.hsplit(a, a.shape[0] // 2)[::2])
# [[[ 0 1] [[ 4 5]
# [ 8 9] [12 13]
# [16 17] [20 21]
# [24 25] , [28 29]
# [32 33] [36 37]
# [40 41] [44 45]
# [48 49] [52 53]
# [56 57]] [60 61]]]
b = np.asarray(np.vsplit(np.hstack(b), a.shape[0] // 2)[::2])
# [[[ 0 1 4 5]
# [ 8 9 12 13]]
# ,
# [[32 33 36 37]
# [40 41 44 45]]]
b = np.vstack(b).squeeze()