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

时间:2019-03-28 16:35:18

标签: python numpy

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

我已经尝试过使用Android Studio并减去矩阵,但是我不确定如何编写没有循环的代码。

例如,给定矩阵:

np.roll

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

2 个答案:

答案 0 :(得分: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

方法2

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

RHS

答案 1 :(得分:3)

您应该能够做类似的事情

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