提取二维二进制数组的索引
Extract indices of a 2D binary array
我有一个由 0 和 1 组成的 numpy 数组(数据)。
import numpy as np
data = np.array([[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0],
[1, 1, **1**, 1, 1, 0],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1]])
我想提取其中“1”被由 1 组成的相邻 5*5 元素包围的索引。
预期索引用星号表示,即 (3,3)。
布尔数组形式的答案也可以。
[[False False False False False False]
[False False False False False False]
[False False **True** False False False]
[False False False False False False]
[False False False False False False]
[False False False False False False]]
我试过
from scipy.ndimage.morphology import binary_erosion
kernel = np.ones((5,5))
result = binary_erosion(data, kernel)
print result
[[False False False False False False]
[False False False False False False]
[False False True False False False]
[False False True False False False]
[False False False False False False]
[False False False False False False]]
它产生了两个 'True' 个位置,但我只想要一个 (3,3)。
怎么做?
编辑:链接问题中显示的解决方案也给出了意想不到的答案。
替代 binary_erosion
,您可以使用 scipy.ndimage.generic_filter
来实现此目的,
from scipy.ndimage import generic_filter
generic_filter(data, np.all, size=(5,5), mode='constant', cval=0).astype(np.bool)
但是你会得到与上面相同的结果,
array([[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]]) # using 1, 0 instead of True, False for readability
因为这是您问题的正确答案。示例矩阵中的 6 行是对称的,对于给定的内核,结果中会有 2 个对称的 True
元素。
如果您想避免这种情况,您可以使用非对称内核大小:size=(6,5)
,尽管这会在第 3 行而不是第 2 行中产生一个真元素。这可以通过手动填充 kernel
使用 binary_erosion
时为零的数组。
另一种类似于@rth
的方法
由于您的数据由 1
和 0
组成,您可以将其放在 int
数组中并使用 uniform_filter
来实现相同的目的:
>>> mask = uniform_filter(data, 5, mode='constant')
>>> mask
array([[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]])
不被个包围的均值小于1
,因为是整型数组,四舍五入为0
要获取第一个索引,您可以执行以下操作:
>>> y, x = np.where(mask)
>>> y[0], x[0]
(2, 2)
我有一个由 0 和 1 组成的 numpy 数组(数据)。
import numpy as np
data = np.array([[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0],
[1, 1, **1**, 1, 1, 0],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1]])
我想提取其中“1”被由 1 组成的相邻 5*5 元素包围的索引。
预期索引用星号表示,即 (3,3)。 布尔数组形式的答案也可以。
[[False False False False False False]
[False False False False False False]
[False False **True** False False False]
[False False False False False False]
[False False False False False False]
[False False False False False False]]
我试过
from scipy.ndimage.morphology import binary_erosion
kernel = np.ones((5,5))
result = binary_erosion(data, kernel)
print result
[[False False False False False False]
[False False False False False False]
[False False True False False False]
[False False True False False False]
[False False False False False False]
[False False False False False False]]
它产生了两个 'True' 个位置,但我只想要一个 (3,3)。
怎么做?
编辑:链接问题中显示的解决方案也给出了意想不到的答案。
替代 binary_erosion
,您可以使用 scipy.ndimage.generic_filter
来实现此目的,
from scipy.ndimage import generic_filter
generic_filter(data, np.all, size=(5,5), mode='constant', cval=0).astype(np.bool)
但是你会得到与上面相同的结果,
array([[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]]) # using 1, 0 instead of True, False for readability
因为这是您问题的正确答案。示例矩阵中的 6 行是对称的,对于给定的内核,结果中会有 2 个对称的 True
元素。
如果您想避免这种情况,您可以使用非对称内核大小:size=(6,5)
,尽管这会在第 3 行而不是第 2 行中产生一个真元素。这可以通过手动填充 kernel
使用 binary_erosion
时为零的数组。
另一种类似于@rth
的方法由于您的数据由 1
和 0
组成,您可以将其放在 int
数组中并使用 uniform_filter
来实现相同的目的:
>>> mask = uniform_filter(data, 5, mode='constant')
>>> mask
array([[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]])
不被个包围的均值小于1
,因为是整型数组,四舍五入为0
要获取第一个索引,您可以执行以下操作:
>>> y, x = np.where(mask)
>>> y[0], x[0]
(2, 2)