我知道Python列表有一个方法可以返回某个对象的第一个索引:

>>> xs = [1, 2, 3]
>>> xs.index(2)
1

NumPy数组也有类似的东西吗?


当前回答

对于1D数组,我推荐np。平坦非零(array == value)[0],它等价于np。非零(array == value)[0][0]和np。其中(array == value)[0][0],但避免了对一个单元素元组开箱的丑陋。

其他回答

是的,给定一个数组,数组和一个值,要搜索的项,你可以使用np。的地方:

itemindex = numpy.where(array == item)

结果是一个元组,首先是所有的行索引,然后是所有的列索引。

例如,如果一个数组是二维的,它包含你的项目在两个位置,那么

array[itemindex[0][0]][itemindex[1][0]]

将等于你的项目,因此将是:

array[itemindex[0][1]][itemindex[1][1]]

对于1D数组,我推荐np。平坦非零(array == value)[0],它等价于np。非零(array == value)[0][0]和np。其中(array == value)[0][0],但避免了对一个单元素元组开箱的丑陋。

只是添加一个非常高性能和方便的numba替代np。Ndenumerate来查找第一个索引:

from numba import njit
import numpy as np

@njit
def index(array, item):
    for idx, val in np.ndenumerate(array):
        if val == item:
            return idx
    # If no item was found return None, other return types might be a problem due to
    # numbas type inference.

这非常快,并且自然地处理多维数组:

>>> arr1 = np.ones((100, 100, 100))
>>> arr1[2, 2, 2] = 2

>>> index(arr1, 2)
(2, 2, 2)

>>> arr2 = np.ones(20)
>>> arr2[5] = 2

>>> index(arr2, 2)
(5,)

这比任何使用np的方法都要快得多(因为它使操作短路)。Where或np. non0。


然而np。Argwhere也可以优雅地处理多维数组(你需要手动将它转换为元组,而且不会短路),但如果没有找到匹配,它就会失败:

>>> tuple(np.argwhere(arr1 == 2)[0])
(2, 2, 2)
>>> tuple(np.argwhere(arr2 == 2)[0])
(5,)

注意:这是python 2.7版本

您可以使用lambda函数来处理这个问题,它既适用于NumPy数组,也适用于列表。

your_list = [11, 22, 23, 44, 55]
result = filter(lambda x:your_list[x]>30, range(len(your_list)))
#result: [3, 4]

import numpy as np
your_numpy_array = np.array([11, 22, 23, 44, 55])
result = filter(lambda x:your_numpy_array [x]>30, range(len(your_list)))
#result: [3, 4]

你可以用

result[0]

获取筛选元素的第一个索引。

对于python 3.6,使用

list(result)

而不是

result

numpy_indexed包(免责声明,我是它的作者)包含一个向量化的等效list。ndarray的索引;那就是:

sequence_of_arrays = [[0, 1], [1, 2], [-5, 0]]
arrays_to_query = [[-5, 0], [1, 0]]

import numpy_indexed as npi
idx = npi.indices(sequence_of_arrays, arrays_to_query, missing=-1)
print(idx)   # [2, -1]

这个解决方案具有向量化的性能,可以推广到ndarray,并且有各种处理缺失值的方法。