给定一个矩阵,我要计算与空(零)像元相邻的填充元素(非零像元)的数量,其中相邻行沿行(左/右)。
我已经尝试过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个与零相邻的非零元素。
方法#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)
| 归档时间: |
|
| 查看次数: |
139 次 |
| 最近记录: |