代码之家  ›  专栏  ›  技术社区  ›  Borys

提取与过滤器匹配的元素

  •  -2
  • Borys  · 技术社区  · 10 年前

    我想过滤足迹(3,3)由1组成的索引。

    import numpy as np
    data = np.array([[1, 1 , 0 , 0 , 0 , 0 , 1 , 0],
                     [1, 1 , 1 , 0 , 0 , 1 , 1 , 0],
                     [1, 1 , 1 , 1 , 1 , 0 , 0 , 0],
                     [0, 0 , 1 , 1 , 1 , 0 , 0 , 0],
                     [0, 0 , 1 , 1 , 1 , 1 , 0 , 1],
                     [1, 1 , 0 , 0 , 0 , 1 , 1 , 1],
                     [1, 1 , 0 , 0 , 0 , 1 , 1 , 1]])
    

    预期答案如下,不需要的位置设置为0:

    answer = np.array([[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                     [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                     [0, 0 , 1 , 1 , 1 , 0 , 0 , 0],
                     [0, 0 , 1 , 1 , 1 , 0 , 0 , 0],
                     [0, 0 , 1 , 1 , 1 , 0 , 0 , 0],
                     [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                     [0, 0 , 0 , 0 , 0 , 0 , 0 , 0]])
    
    1 回复  |  直到 10 年前
        1
  •  3
  •   Community CDub    8 年前

    我的答案是基于 a very similar answer 我几小时前才写信。

    #from sklearn.feature_extraction.image import extract_patches  # similar to numpy's stride_tricks
    from numpy.lib.stride_tricks import as_strided
    
    data = np.array([[1, 1 , 0 , 0 , 0 , 0 , 1 , 0],
                     [1, 1 , 1 , 0 , 0 , 1 , 1 , 0],
                     [1, 1 , 1 , 1 , 1 , 0 , 0 , 0],
                     [0, 0 , 1 , 1 , 1 , 0 , 0 , 0],
                     [0, 0 , 1 , 1 , 1 , 1 , 0 , 1],
                     [1, 1 , 0 , 0 , 0 , 1 , 1 , 1],
                     [1, 1 , 0 , 0 , 0 , 1 , 1 , 1]])
    patches = as_strided(data, shape=(data.shape[0]-2,data.shape[1]-2, 3, 3), strides=data.strides*2)
    dual = patches.all(axis=-1).all(axis=-1)
    patches[dual==False] = 0
    patches[dual] = 1
    

    结果(在 data )正如你所展示的。

    其工作方式如下: 函数 extract_patches 生成 视图 到阵列中 数据 ,这意味着它是 实际数据的副本,但使用 跨步 以生成看似不同的阵列。在这种情况下,它将生成阵列的所有可能的3x3子矩阵(可以重叠) 数据 。然后,通过写作 patches.all(axis=-1).all(axis=-1) ,您首先要检查子矩阵行中的元素是否都为True(或在布尔意义上等同于True,因此不是0、空列表、空字典、空元组和其他一些特殊情况),从而折叠此数组的一个轴,然后使用第二个轴 .all(axis=-1) 正在检查这些列是否都为True。

    本段的小示例可直观地阐明:

    >>> A = np.array([
    ... [1, 1, 0],        # -> along this row, not all elements are 1: so `all` along the last axis will return False
    ... [1, 1, 1],        # -> along this row, all elements are 1: so `all` along the last axis (axis=-1) will return True
    ... [1, 1, 1]])
    >>> A.all(axis=-1)
    array([False,  True,  True], dtype=bool)  # so it is done along the last axis, along the rows
    >>> A.all(axis=-1).all(axis=-1)
    False
    

    所以这个数组 dual 现在每个3x3子矩阵都有一个“1”(实际上是真的)。然而,这些子矩阵是重叠的,因此,当这些3x3子矩阵中的每一个子矩阵都不全是1时(这是第一个代码块中的最后一行: patches[dual==False] = 0 )以及 然后 您可以在每个3x3子矩阵中再次应用这些1,这些子矩阵最初都是1。 备选方案与 kernel = np.ones((3,3)) 或者考虑多个按位操作(如另一个答案),但是当数组的维数超过简单的 (2,2) .