Reputation: 65
I have a set of 2d arrays that hold latitudes and longitudes for a map area, with a binary mask that denotes land (0) or ocean (1). What I am interested in doing is extracting the indices for all coastal ocean elements (mask elements 1 that are adjacent to a 0, including diagonally) so that I can use those indices to extract the lats+lons of all coastal elements from the other arrays.
Given an array:
a = np.array([[1, 1, 1, 1, 1],
[1, 1, 0, 1, 1],
[1, 0, 0, 0, 1],
[1, 1, 0, 1, 1],
[1, 1, 1, 1, 1]])
I'm looking for a way to return:
(array([0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4]),
array([1, 2, 3, 0, 1, 3, 4, 0, 4, 0, 1, 3, 4, 1, 2, 3]))
where each array has the indices for each axis.
This output format is similar to np.where(), I guess what I'm trying to do is np.where(a == adjacent to 0).
Upvotes: 4
Views: 388
Reputation: 150745
Let's try convolve2d
:
from scipy.signal import convolve2d
kernel = np.full((3,3), 1)
# remove center of kernel -- not count 1 at the center of the square
# we may not need to remove center
# in which case change the mask for counts
kernel[1,1]=0
# counts 1 among the neighborhoods
counts = convolve2d(a, kernel, mode='same',
boundary='fill', fillvalue=1)
# counts==8 meaning surrounding 8 neighborhoods are all 1
# change to 9 if we leave kernel[1,1] == 1
# and we want ocean, i.e. a==1
np.where((counts != 8) & (a==1))
Output:
(array([0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4]),
array([1, 2, 3, 0, 1, 3, 4, 0, 4, 0, 1, 3, 4, 1, 2, 3]))
Upvotes: 3