【问题标题】:Neighbors in a 2D array python二维数组python中的邻居
【发布时间】:2021-05-23 07:08:55
【问题描述】:

我有一个 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]
                 ])

在我看来,这是一个众所周知的问题,但我什至没有弄清楚如何在搜索中制定它,因为我正在寻找的一切都有些不同。 最好的方法是什么?

【问题讨论】:

    标签: python arrays algorithm numpy matrix


    【解决方案1】:

    您可以使用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]]
    

    【讨论】:

      【解决方案2】:

      您可以将scipy.ndimage labeling函数与自定义结构数组s一起使用:

      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]]
      

      我确信substituting the label number 的最后一步及其出现的值可以在速度方面进行优化。
      并且@mad-physicist 正确地提到最初使用的labeledarr.flat 应该被labeledarr.ravel() 替换。 The reasons for this are explained here.

      【讨论】:

      • 拉威尔可能比平面更可取
      猜你喜欢
      • 2017-10-04
      • 2010-10-13
      • 2013-04-08
      • 1970-01-01
      • 2017-12-23
      • 2016-08-26
      • 2012-06-15
      • 1970-01-01
      相关资源
      最近更新 更多