[英]Find number of non-zero elements adjacent to zeros in numpy 2D array
给定矩阵,我想计算与空(零)单元相邻的填充元素(非零单元)的数量,其中邻接沿着行(左/右)。
我尝试过使用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]]
我们有12个与零相邻的非零元素。
方法#1
我们可以使用2D convolution
在zeros
掩码上使用适当的内核([1,1,1])
或([1,0,1])
来解决它,并查找卷积求和>=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
方法#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()
你应该能够做类似的事情
ar = a[:,1:] & ~a[:,:-1]
al = a[:,:-1] & ~a[:,1:]
al[:, 0].sum() + (al[:, 1:] | ar[:, :-1]).sum() + ar[:, -1].sum() # 12
在这里,想法是ar
跟踪0右边的那些1,而al
跟踪0左边的那些1,然后我们注意不要重复计数。
如果您不介意使用转置,整个过程会变得更简洁:
b = a.T
br = b[1:] & ~b[:-1]
bl = b[:-1] & ~b[1:]
bl[0].sum() + (bl[1:] | br[:-1]).sum() + br[-1].sum() # Also 12
一个可能更易读的版本,可以避免必须单独处理两个边缘,将b[1:]
和b[:-1]
用一列扩展:
edge = np.ones(9, int)
(b & ~(np.vstack([b[1:], edge]) & np.vstack([edge, b[:-1]]))).sum() # Also 12
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.