计算 numpy 数组中具有 2 个或更多邻居的单元格数

Calculate number of cells with 2 neighboors or more, within a numpy array

我正在努力实现与此类似的目标 。 objective是统计至少有两个直接邻居(上、下、左、右)的1的个数,与我的版本唯一不同的是序列中必须至少有一个交叉或角。

例如,

array([[0, 0, 0, 0, 0, 1],
       [0, 1,*1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0],
       [1, 1, 0, 1, 1, 0],
       [1, 0, 0, 0, 1, 0]])

带星标的 *1 不算在内,因为它的邻居没有形成角或十字。右上角 1 也没有,因为它没有两个邻居。答案是 2(右下角和左下角)。

这是我尝试过的:

import numpy as np
a = np.zeros((6,6), dtype=np.int)
a[0,5] = 1
a[1,1] = a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1
a[3,0] = a[4,0] = a[5,0] = a[4,1] = 1

from scipy import ndimage
kernel = ndimage.generate_binary_structure(2, 1)
kernel[1, 1] = 0

b = convolve(a, kernel, mode="constant")
c = b[a>0]

# At least 2 neighbours
return len(c[c >= 2])

但它仍然从第二行开始计算加星标的 *1(returns 3 而不是 2)!

感谢您的帮助!

您正在尝试二维卷积。您可能想尝试一个“十字形”内核,这将导致相关单元格的 3 或更多(=1+2,1 来自中心的 1,2 来自邻居)。 signal.convolve2d 来自 scipy 完成此操作,如下所示:

import numpy as np
from scipy import ndimage
from scipy import signal

a = np.zeros((6,6), dtype=np.int)
a[0,5] = 1
a[1,1] = a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1
a[3,0] = a[4,0] = a[5,0] = a[4,1] = 1

print(a)

#kernel = ndimage.generate_binary_structure(2, 1)
#kernel[1, 1] = 0
kernel = np.array([[0,1,0], [1,1,1], [0,1,0]])

#b = np.convolve(a, kernel, mode="constant")
#c = b[a>0]
b = signal.convolve2d(a, kernel, mode='same')

# At least 2 neighbours
#return len(c[c >= 2])
print(b)
print(np.where(b > 2, b, 0))

产生(我用 np.where 过滤了结果):

[[0 0 0 0 0 1]
 [0 1 1 1 0 0]
 [0 0 0 0 0 0]
 [1 0 0 0 0 0]
 [1 1 0 1 1 0]
 [1 0 0 0 1 0]]
[[0 1 1 1 1 1]
 [1 2 3 2 1 1]
 [1 1 1 1 0 0]
 [2 2 0 1 1 0]
 [4 2 2 2 3 1]
 [2 2 0 2 2 1]]
[[0 0 0 0 0 0]
 [0 0 3 0 0 0]
 [0 0 0 0 0 0]
 [0 0 0 0 0 0]
 [4 0 0 0 3 0]
 [0 0 0 0 0 0]]

已正确识别 1 的位置(3 或 4)。

您的标准可以重述为“至少一个水平邻居和至少一个垂直邻居”。因此,无论您最终选择的邻居检测是不是在 2D 中,而是在 1D 中选择两次,一次是水平的,一次是垂直的:

例如,使用 scipy.ndimage 提供 convolve1d:

import scipy.ndimage as sn

(sn.convolve1d(in_,(1,3,1),axis=0,mode="constant")>>2) & (sn.convolve1d(in_,(1,3,1),axis=1,mode="constant")>>2)
# array([[0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0],
#        [1, 0, 0, 0, 1, 0],
#        [0, 0, 0, 0, 0, 0]])

in_ 是 OP 中的示例数组。)