【问题标题】:Replace values in an 2d array according to neighboring values根据相邻值替换二维数组中的值
【发布时间】:2016-07-18 04:12:04
【问题描述】:

我有一个数组 (n,m):

 [255 100 255]
 [100 255 100]
 [255 100 255]

我需要创建一个像这样的新数组,其中测试相邻值,如果北、东、南、西都等于 100,我的值设置为 100:

 [255 100 255]
 [100 100 100]
 [255 100 255]

我有一个简单的解决方案,可以在 1:n 和 1:m 上循环,但它显然非常慢,我想知道是否有更快的方法。 我发现几个链接都在谈论滑动窗口来计算平均值,但我不知道如何跟踪我的索引来创建新数组。 Using strides for an efficient moving average filter

提前感谢您的意见。

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    假设A 作为输入数组,这里是使用slicingboolean indexing 的一种方法-

    # Get west, north, east & south elements for [1:-1,1:-1] region of input array
    W = A[1:-1,:-2]
    N  = A[:-2,1:-1]
    E = A[1:-1,2:]
    S  = A[2:,1:-1]
    
    # Check if all four arrays have 100 for that same element in that region
    mask = (W == 100) & (N == 100) & (E == 100) & (S == 100)
    
    # Use the mask to set corresponding elements in a copy version as 100s
    out = A.copy()
    out[1:-1,1:-1][mask] = 100
    

    示例运行 -

    In [90]: A
    Out[90]: 
    array([[220,  93, 205,  82,  23, 210,  22],
           [133, 228, 100,  27, 210, 186, 246],
           [196, 100,  73, 100,  86, 100,  53],
           [195, 131, 100, 142, 100, 214, 100],
           [247,  73, 117, 116,  24, 100,  50]])
    
    In [91]: W = A[1:-1,:-2]
        ...: N  = A[:-2,1:-1]
        ...: E = A[1:-1,2:]
        ...: S  = A[2:,1:-1]
        ...: mask = (W == 100) & (N == 100) & (E == 100) & (S == 100)
        ...: 
        ...: out = A.copy()
        ...: out[1:-1,1:-1][mask] = 100
        ...: 
    
    In [92]: out
    Out[92]: 
    array([[220,  93, 205,  82,  23, 210,  22],
           [133, 228, 100,  27, 210, 186, 246],
           [196, 100, 100, 100,  86, 100,  53],
           [195, 131, 100, 142, 100, 100, 100],
           [247,  73, 117, 116,  24, 100,  50]])
    

    此类问题主要出现在信号处理/图像处理领域。因此,您也可以使用 2D convolution 作为替代解决方案,就像这样 -

    from scipy import signal
    from scipy import ndimage
    
    # Use a structuring elements with north, west, east and south elements as 1s
    strel = ndimage.generate_binary_structure(2, 1)
    
    # 2D Convolve to get 4s at places that are surrounded by 1s
    mask = signal.convolve2d((A==100).astype(int),strel,'same')==4
    
    # Use the mask to set corresponding elements in a copy version as 100
    out = A.copy()
    out[mask] = 100
    

    示例运行 -

    In [119]: A
    Out[119]: 
    array([[108, 184,   0, 176, 131,  86, 201],
           [ 22,  47, 100,  78, 151, 196, 221],
           [185, 100, 142, 100, 121, 100,  24],
           [201, 101, 100, 138, 100,  20, 100],
           [127, 227, 217,  19, 206, 100,  43]])
    
    In [120]: strel = ndimage.generate_binary_structure(2, 1)
         ...: mask = signal.convolve2d((A==100).astype(int),strel,'same')==4
         ...: 
         ...: out = A.copy()
         ...: out[mask] = 100
         ...: 
    
    In [121]: out
    Out[121]: 
    array([[108, 184,   0, 176, 131,  86, 201],
           [ 22,  47, 100,  78, 151, 196, 221],
           [185, 100, 100, 100, 121, 100,  24],
           [201, 101, 100, 138, 100, 100, 100],
           [127, 227, 217,  19, 206, 100,  43]])
    

    更直接的方法是使用ndimage.binary_closing,这正是closing 的预期操作。所以,另一种获取面具的方法是 -

    strel = ndimage.generate_binary_structure(2, 1)
    mask = ndimage.binary_closing(A==100, structure=strel)
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 2015-09-28
    • 2017-05-04
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    相关资源
    最近更新 更多