这是一个矩阵。
1 2 1
1 1 0
0 1 1
我正试图获得直接链接到数字2的数字1的所有索引,即[0,0],[0,2]和[1,1]
ds = np.array([[1, 2, 1],
[1, 1, 0],
[0, 1, 1]])
p0 = np.where(ds == 2)
p1 = np.where(ds == 1)
d1 = np.array(p1) - np.array(p0)
idx = np.where(np.linalg.norm(d1,axis=0, keepdims=True) == 1)[1]
np.take(p1, idx, axis=1 )
如果2个以上,则需要分别存储2个邻居。
虽然这段代码有效,但我想知道是否有更有效的方法来做到这一点?
答案 0 :(得分:1)
首先,如果数组中的2个以上,则您的代码将无法工作,因此您需要一种更通用的方法。
根据您的期望,如果两个索引的一个轴相同,而另一个轴相差1个单位,则它们是相邻的。
X
X O X
X
现在,如果您有一个如下数组:
In [87]: arr # I changed the value of [2, 2] index to 2
Out[87]:
array([[1, 2, 1],
[1, 1, 0],
[0, 1, 2]])
您可以通过以下矢量化方法来找到预期的印章:
In [88]: one_indices = np.argwhere(arr==1)
In [89]: two_indices = np.argwhere(arr==2)
In [90]: x, y = np.where(two_indices[:, 0][:,None] == one_indices[:, 0])
In [91]: neighbor_on_row = one_indices[y[np.where(np.abs(one_indices[:, 1][y] - two_indices[:, 1][x]) == 1)[0]]]
In [92]: neighbor_on_row
Out[92]:
array([[0, 0],
[0, 2],
[2, 1]])
In [93]: x, y = np.where(two_indices[:, 1][:,None] == one_indices[:, 1])
In [94]: neighbor_on_col = one_indices[y[np.where(np.abs(one_indices[:, 0][y] - two_indices[:, 0][x]) == 1)[0]]]
In [95]: neighbor_on_col
Out[95]: array([[1, 1]])
最后:
In [103]: np.concatenate((neighbor_on_row, neighbor_on_col))
Out[103]:
array([[0, 0],
[0, 2],
[2, 1],
[1, 1]])
答案 1 :(得分:1)
代码:
ds = np.array([[1, 2, 1],
[1, 1, 0],
[0, 1, 2]])
p0 = np.where(ds == 2)
p0 = np.array(p0)
p1 = np.where(ds == 1)
for i in range(len(p0[0])):
d1 = np.array(p1) - p0[:,i].reshape(2,1)
idx = np.where(np.linalg.norm(d1,axis=0, keepdims=True) == 1)[1]
print('neighbors of', p0[:,i])
print(np.take(p1, idx, axis=1))
输出:
neighbors of [0 1]
[[0 0 1]
[0 2 1]]
neighbors of [2 2]
[[2]
[1]]
答案 2 :(得分:0)
我认为您可以使用open-cv
库中的形态学dilation来尝试您的方法,而我用该操作编写的方法和我的方法要快两倍。我还尝试了scipy
implementation of dilation,但是它比您的实现花费了更多时间。
如果可以使用open-cv,则此代码可能对您有用:
kernel = np.array([[0, 1, 0],
[1, 1, 1],
[0, 1, 0]], dtype=np.uint8)
def get_twoes_neighbor2(ds, kernel):
img = (ds == 2).astype(np.uint8)
img_dilation = cv2.dilate(img, kernel, iterations=1)
neighbors = (ds == 1) & img_dilation
return np.array(np.where(neighbors == 1))