Python 提取二维二进制数组的索引

Python 提取二维二进制数组的索引,python,numpy,scipy,scikit-learn,scikit-image,Python,Numpy,Scipy,Scikit Learn,Scikit Image,我有一个由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], [

我有一个由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]]
它产生了两个“真实”的位置,但我只想要一个(3,3)

怎么做


编辑:链接问题中显示的解决方案也给出了意外的答案。

除了
二进制
,您还可以使用
scipy.ndimage.generic_过滤器
来实现这一点

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行生成一个true元素。这是可以修复的,当使用
binary\u
时,手动用零填充
内核
数组

另一种类似于@rth的方法

由于您的数据由
1
0
组成,因此您可以将其放入
int
数组中,并使用a来实现相同的功能:

>>> 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包围的1的平均值小于
1
,并四舍五入到
0
,因为它是一个整数数组

要获取第一个索引,可以执行以下操作:

>>> y, x = np.where(mask)
>>> y[0], x[0]
(2, 2)

谢谢你的解释和回答。不可能从左上角位置仅读取5列5行的数据;然后,如果所有元素都是1,则提取它的中间索引,依此类推。
scipy.ndimage
使用像素,而它根本没有“中间像素或中间索引”的概念。当然,也可以这样做,例如,通过使用
ndimage.zoom
执行
binary\u
并返回到初始分辨率来提高分辨率。仍然是因为,原始阵列是上下对称的,所以必须以某种方式打破这种对称性才能获得1个像素。标记为
True
的第二个元素也被一个5x5的
1
s框包围。。。你为什么不喜欢呢?@6502是因为从第一个真的已经占据的位置数1。我想避免重复@Divakar可能的重复不,我在提问之前看到了这个问题,但问题中显示的解决方案也给出了出乎意料的答案,正如我在问题中所坚持的那样。