【问题标题】:Calculate number of cells with 2 neighboors or more, within a numpy array计算 numpy 数组中具有 2 个或更多邻居的单元格数
【发布时间】:2020-12-19 02:20:42
【问题描述】:

我正在努力实现与question 类似的目标。 目标是计算至少有两个直接邻居(上、下、左、右)的 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(返回 3 而不是 2)!

感谢您的帮助!

【问题讨论】:

    标签: python numpy multidimensional-array scipy mathematical-morphology


    【解决方案1】:

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

    例如,使用提供convolve1dscipy.ndimage

    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 中的示例数组。)

    【讨论】:

      【解决方案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)。

      【讨论】:

        猜你喜欢
        • 2012-09-18
        • 1970-01-01
        • 2016-07-21
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 2017-03-24
        • 2021-11-14
        • 1970-01-01
        相关资源
        最近更新 更多