二维数组Python中的邻居

3

我有一个2D numpy数组,如下所示:

start = np.array([
    [1,1,0,1],
    [1,0,0,1],
    [0,1,0,0]
                ])

我需要获取相同的矩阵,但将每个值替换为通过向任何方向移动一步,但仅沿着1行走可以到达的邻居数量。

结果应该如下:

finish = np.array([
    [4,4,0,2],
    [4,0,0,2],
    [0,4,0,0]
                 ])

在我看来,这似乎是一个广为人知的问题,但我甚至还没有想出如何在搜索中明确表述它,因为我查找到的所有内容都有些不同。

最好的解决方法是什么?

2个回答

2
您可以使用自定义结构数组sscipy.ndimage标记函数。
import numpy as np
from scipy.ndimage import label    

start = np.asarray([ [1,1,0,1],
                   [1,0,0,1],
                   [0,1,0,0] ])

#structure array what to consider as "neighbors"
s = [[1,1,1],
     [1,1,1],
     [1,1,1]]

#label blobs in array
labeledarr,_ = label(start, structure=s)

#retrieve blobs and the number of elements within each blobs
blobnr, blobval = np.unique(labeledarr.ravel(), return_counts=True)

#substitute blob label with the number of elements
finish = np.zeros_like(labeledarr)
for k, v in zip(blobnr[1:], blobval[1:]):
    finish[labeledarr==k] = v

print(finish)

输出:

[[4 4 0 2]
 [4 0 0 2]
 [0 4 0 0]]

我确信用出现次数的值替换标签号码的最后一步可以在速度方面优化。
而且 @mad-physicist 正确地指出最初使用的 labeledarr.flat 应该被替换为 labeledarr.ravel()这里解释了原因

1
Ravel可能比flat更可取。 - Mad Physicist

0

您可以使用scipy.ndimage.label来标记连接区域并返回区域数量,正如@Mr.T所指出的那样。然后可以使用它来创建布尔掩码以进行索引和计数。

应该归功于@Mr.T,因为他首先提出了类似的解决方案。尽管这个答案的第二部分不同,但我发现它更易读,并且在我的机器上快40%。

import numpy as np
from scipy.ndimage import label

a = [[1,1,0,1],
     [1,0,0,1],
     [0,1,0,0]]) 

# Label connected regions, the second arg defines the connection structure
labeled, n_labels = label(a, np.ones((3,3)))

# Replace label value with the size of the connected region
b = np.zeros_like(labeled)
for i in range(1, n_labels+1):
    target = (labeled==i)
    b[target] = np.count_nonzero(target)

print(b)

输出:

[[4 4 0 2]
 [4 0 0 2]
 [0 4 0 0]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接