我想过滤其足迹(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]])
答案 0 :(得分:3)
我的答案基于我几小时前写的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
在数组data
中生成视图,这意味着不是实际数据的副本,但使用大步生成一个看似不同的数组。在这种情况下,它将生成数组data
的所有可能的3x3子矩阵(可以重叠)。然后,通过编写patches.all(axis=-1).all(axis=-1)
,您首先要检查子矩阵行中的元素是否全为True(或者在布尔意义上等效为True,因此不是0,空列表,空字典,空元组和a很少有其他特殊情况),从而折叠这个数组的一个轴,然后用第二个.all(axis=-1)
正在检查列,看它们是否都是真的。
本段的一个小例子,以视觉上澄清:
>>> 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
因此,对于每个充满1的3x3子矩阵,此数组dual
现在具有“1”(实际为真)。然而,这些子矩阵是重叠的,所以你首先想要将这些补丁全部设置为0,而这些3x3子矩阵中的任何一个都不是全部(这是第一个代码块中的一到最后一行:patches[dual==False] = 0
)和< em>然后你可以在最初拥有所有的3x3子矩阵中再次应用那些。
替代方案是与kernel = np.ones((3,3))
相关联或考虑多个按位操作(如在另一个答案中),但当数组的维度超出简单(2,2)
时,最后一个方法变得非常难以编写。