从满足布尔条件的NumPy数组中获取(列,行)索引

Adr*_*ock 8 python arrays numpy

我正在使用2D NumPy数组.我想得到(列,行)索引,或者(x,y)坐标,如果你更喜欢这样,我的2D数组符合布尔条件.

我能解释我想要做的最好的方法是通过一个简单的例子:

>>> a = np.arange(9).reshape(3, 3)
>>> b = a > 4
>>> b
>>> array([[False, False, False],
           [False, False,  True],
           [ True,  True,  True]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

此时我现在有一个布尔数组,指示在哪里a > 4.

此时我的目标是获取值为的布尔数组的索引True.例如,索引(1, 2),(2, 0),(2, 1),和(2, 2)所有有真值.

我的最终目标是最终得到一个索引列表:

>>> indexes = [(1, 2), (2, 0), (2, 1), (2, 2)]
Run Code Online (Sandbox Code Playgroud)

同样,我强调指出上面的代码是一个简单的例子,但我正在尝试做的事情的应用可能有任意索引,a > 4而不是基于arange和的东西reshape.

Ash*_*ary 17

使用numpy.wherenumpy.column_stack:

>>> np.column_stack(np.where(b))
array([[1, 2],
       [2, 0],
       [2, 1],
       [2, 2]])
Run Code Online (Sandbox Code Playgroud)


ev-*_*-br 5

@Ashwini Chaudhary答案的另一种选择是numpy.nonzero

>>> a = np.arange(9).reshape(3,3)
>>> b = a > 4
>>> np.nonzero(b)
(array([1, 2, 2, 2]), array([2, 0, 1, 2]))

>>> np.transpose(np.nonzero(b))
array([[1, 2],
       [2, 0],
       [2, 1],
       [2, 2]])
Run Code Online (Sandbox Code Playgroud)

编辑:什么是更快.nonzero并且where本质上是等价的,但transpose在这里证明是错误的(即使它在文档中提到):

In [15]: N = 5000

In [16]: a = np.random.random((N, N))

In [17]: %timeit np.nonzero(a > 0.5)
1 loops, best of 3: 470 ms per loop

In [18]: %timeit np.transpose(np.nonzero(a > 0.5))     # ooops
1 loops, best of 3: 2.56 s per loop

In [19]: %timeit np.where(a > 0.5)
1 loops, best of 3: 467 ms per loop

In [20]: %timeit np.column_stack(np.where(a > 0.5))
1 loops, best of 3: 653 ms per loop
Run Code Online (Sandbox Code Playgroud)