给定一个矩阵,我要计算与空(零)像元相邻的填充元素(非零像元)的数量,其中相邻元素沿着行(左/右)。
我已经尝试过使用Android Studio
并减去矩阵,但是我不确定如何编写没有循环的代码。
例如,给定矩阵:
np.roll
我们有12个与零相邻的非零元素。
答案 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