在numpy 2D数组中查找与零相邻的非零元素的数量

Geo*_*ell 5 python numpy

给定一个矩阵,我要计算与空(零)像元相邻的填充元素(非零像元)的数量,其中相邻行沿行(左/右)。

我已经尝试过np.roll和减去矩阵,但我不确定如何编写没有循环的代码。

例如,给定矩阵:

arr = 
[[1 1 0 0 0 0 0 0 1 0]
 [1 1 0 0 0 0 0 1 1 1]
 [0 1 1 0 0 0 0 0 0 0]
 [0 1 1 0 0 0 0 0 0 0]
 [0 1 1 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]
Run Code Online (Sandbox Code Playgroud)

我们有12个与零相邻的非零元素。

Div*_*kar 3

方法#1

我们可以使用2D convolution适当的内核([1,1,1])或([1,0,1])掩码来解决它zeros,并寻找卷积总和为>=1,这表示三个元素的每个滑动窗口中至少有一个零,并且对当前元素是否非零进行额外检查以确认至少有一个邻居0。

实现看起来像这样 -

In [245]: a  # input array
Out[245]: 
array([[1, 1, 0, 0, 0, 0, 0, 0, 1, 0],
       [1, 1, 0, 0, 0, 0, 0, 1, 1, 1],
       [0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

In [246]: from scipy.signal import convolve2d

In [248]: k = [[1,1,1]] # kernel for convolution

In [249]: ((convolve2d(a==0,k,'same')>=1) & (a!=0)).sum()
Out[249]: 12
Run Code Online (Sandbox Code Playgroud)

方法#2

另一种方法是利用,slicing因为我们将沿着每一行寻找一次性偏移元素,以查找左侧和右侧的零和非零匹配LHS,RHS最后将它们相加 -

maskRHS = (a[:,1:]==0) & (a[:,:-1]!=0)
maskLHS = (a[:,1:]!=0) & (a[:,:-1]==0)
maskRHS[:,1:] |= maskLHS[:,:-1]
out = maskRHS.sum() + maskLHS[:,-1].sum()
Run Code Online (Sandbox Code Playgroud)