Reputation: 21961
I want to extract the cells in orange and green separately in the following numpy array:
I could do it by hard coding e.g. arr[0, 1] refers to the top left grid cell. Is there a way to do it more elegantly?
Upvotes: 1
Views: 308
Reputation: 1740
Suppose you have a N*N
array called a
, you can simply do:
np.concatenate((a[k:-k:N-2*k-1,k:-k], a[k+1:-k-1,k:-k:N-2*k-1]), None)
to extract the k
th round (starting from zero), where the first slice stands for two rows, the second slice stands for two columns.
Example (output sorted for easier verification):
N = 8
k = 1
a = np.arange(N * N).reshape(N, N)
print(a)
print(np.sort(np.concatenate((a[k:-k:N-2*k-1,k:-k], a[k+1:-k-1,k:-k:N-2*k-1]), None)))
which will output:
[[ 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]]
[ 9 10 11 12 13 14 17 22 25 30 33 38 41 46 49 50 51 52 53 54]
Upvotes: 3
Reputation: 5958
Use a boolean mask
array:
arr = np.random.permutation(np.arange(25)).reshape(5,5)
>>> arr
array([[15, 9, 7, 1, 22],
[16, 4, 2, 19, 13],
[12, 3, 23, 8, 6],
[ 0, 20, 21, 10, 14],
[18, 5, 24, 11, 17]])
Above is building a random matrix for this purpose.
# Build mask
mask = np.ones((5,5)) == True
mask[1:4, 1:4] = False
>>> mask
array([[ True, True, True, True, True],
[ True, False, False, False, True],
[ True, False, False, False, True],
[ True, False, False, False, True],
[ True, True, True, True, True]])
# Extract values:
>>> arr[mask]
array([15, 9, 7, 1, 22, 16, 13, 12, 6, 0, 14, 18, 5, 24, 11, 17])
Build next mask for inner circle:
mask = np.ones((5,5)) == False
mask[1:4, 1:4] = True
mask[2,2] = False
>>> mask
array([[False, False, False, False, False],
[False, True, True, True, False],
[False, True, False, True, False],
[False, True, True, True, False],
[False, False, False, False, False]])
arr[mask]
>>> array([ 0, 15, 20, 16, 4, 1, 6, 8])
Upvotes: 1