簡體   English   中英

在numpy 2D數組中查找與零相鄰的非零元素的數量

[英]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 convolutionzeros掩碼上使用適當的內核([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因為我們會在左右兩側LHSRHS的零和非零匹配中尋找沿着每一行的一次性偏移元素,最后總結那些 -

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM