我知道Python列表有一种方法可以返回第一个索引:

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

NumPy数组有类似内容吗?

有帮助吗?

解决方案

是的,这里给出了一个NumPy数组, array 和一个值 item 的答案,用于搜索:

itemindex = numpy.where(array==item)

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

例如,如果一个数组是两个维度,并且它在两个位置包含您的项目,那么

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

将等于您的项目,因此

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

numpy.where

其他提示

如果您需要第一次出现只有一个值的索引,您可以使用非零(或 where ,相当于同样的事情):

>>> t = array([1, 1, 1, 2, 2, 3, 8, 3, 8, 8])
>>> nonzero(t == 8)
(array([6, 8, 9]),)
>>> nonzero(t == 8)[0][0]
6

如果您需要每个多个值的第一个索引,您显然可以反复执行上述操作,但有一个技巧可能更快。以下内容查找每个子序列的第一个元素的索引

>>> nonzero(r_[1, diff(t)[:-1]])
(array([0, 3, 5, 6, 7, 8]),)

请注意,它找到了3的子序列的开头和8s的两个子序列:

[ 1 ,1,1, 2 ,2, 3 8 3 8 ,8]

所以它与找到每个值的第一个出现略有不同。在您的程序中,您可以使用 t 的排序版本来获得您想要的内容:

>>> st = sorted(t)
>>> nonzero(r_[1, diff(st)[:-1]])
(array([0, 3, 5, 7]),)

您还可以将NumPy数组转换为空中列表并获取其索引。例如,

l = [1,2,3,4,5] # Python list
a = numpy.array(l) # NumPy array
i = a.tolist().index(2) # i will return index of 2
print i

它会打印1。

如果您要将其用作其他内容的索引,则可以使用布尔索引(如果数组是可广播的);你不需要明确的指数。绝对最简单的方法是简单地根据真值进行索引。

other_array[first_array == item]

任何布尔操作都有效:

a = numpy.arange(100)
other_array[first_array > 50]

非零方法也需要布尔值:

index = numpy.nonzero(first_array == item)[0][0]

两个零用于索引的元组(假设first_array是1D),然后是索引数组中的第一个项。

l.index(x)返回最小的 i ,以便 i 是列表中第一次出现x的索引。

可以安全地假设Python中的 index()函数已经实现,以便在找到第一个匹配项后停止,这样可以获得最佳的平均性能。

要查找在NumPy数组中第一次匹配后停止的元素,请使用迭代器( ndenumerate )。

In [67]: l=range(100)

In [68]: l.index(2)
Out[68]: 2

NumPy数组:

In [69]: a = np.arange(100)

In [70]: next((idx for idx, val in np.ndenumerate(a) if val==2))
Out[70]: (2L,)

请注意,如果找不到元素,则 index() next 这两个方法都会返回错误。使用 next ,可以使用第二个参数在未找到元素的情况下返回特殊值,例如

In [77]: next((idx for idx, val in np.ndenumerate(a) if val==400),None)

NumPy中还有其他函数( argmax where nonzero ),可用于查找数组中的元素,但它们都有缺点,即遍历整个数组寻找所有次出现,因此没有针对查找第一个元素进行优化。另请注意 where nonzero 返回数组,因此您需要选择第一个元素来获取索引。

In [71]: np.argmax(a==2)
Out[71]: 2

In [72]: np.where(a==2)
Out[72]: (array([2], dtype=int64),)

In [73]: np.nonzero(a==2)
Out[73]: (array([2], dtype=int64),)

时间比较

只检查大型数组,当搜索项位于数组的开头时,使用迭代器的解决方案更快(使用IPython shell中的%timeit ) :

In [285]: a = np.arange(100000)

In [286]: %timeit next((idx for idx, val in np.ndenumerate(a) if val==0))
100000 loops, best of 3: 17.6 µs per loop

In [287]: %timeit np.argmax(a==0)
1000 loops, best of 3: 254 µs per loop

In [288]: %timeit np.where(a==0)[0][0]
1000 loops, best of 3: 314 µs per loop

这是一个公开的 NumPy GitHub问题

另请参阅: Numpy:快速找到第一个价值指数

要对任何条件进行索引,您可以执行以下操作:

In [1]: from numpy import *
In [2]: x = arange(125).reshape((5,5,5))
In [3]: y = indices(x.shape)
In [4]: locs = y[:,x >= 120] # put whatever you want in place of x >= 120
In [5]: pts = hsplit(locs, len(locs[0]))
In [6]: for pt in pts:
   .....:         print(', '.join(str(p[0]) for p in pt))
4, 4, 0
4, 4, 1
4, 4, 2
4, 4, 3
4, 4, 4

这里有一个快速的函数来执行list.index()所做的事情,除非没有找到它引发异常。注意 - 这在大型阵列上可能非常慢。如果你更愿意将它作为一种方法使用,你可以将它修补到数组上。

def ndindex(ndarray, item):
    if len(ndarray.shape) == 1:
        try:
            return [ndarray.tolist().index(item)]
        except:
            pass
    else:
        for i, subarray in enumerate(ndarray):
            try:
                return [i] + ndindex(subarray, item)
            except:
                pass

In [1]: ndindex(x, 103)
Out[1]: [4, 0, 3]

对于1D数组,我建议 np.flatnonzero(array == value)[0] ,这相当于 np.nonzero(array == value)[0 ] [0] np.where(array == value)[0] [0] 但避免了取消装箱1元组元组的丑陋。

NumPy中有很多操作可能可以放在一起来完成这个任务。这将返回元素的索引等于item:

numpy.nonzero(array - item)

然后,您可以获取列表的第一个元素以获得单个元素。

对于一维排序数组,使用 numpy.searchsorted 返回NumPy整数(位置)。例如,

arr = np.array([1, 1, 1, 2, 3, 3, 4])
i = np.searchsorted(arr, 3)

确保数组已经排序

同时检查返回的索引i是否实际包含搜索的元素,因为searchsorted的主要目标是查找应插入元素以保持顺序的索引。

if arr[i] == 3:
    print("present")
else:
    print("not present")

从np.where()中选择第一个元素的另一种方法是使用生成器表达式和枚举,例如:

>>> import numpy as np
>>> x = np.arange(100)   # x = array([0, 1, 2, 3, ... 99])
>>> next(i for i, x_i in enumerate(x) if x_i == 2)
2

对于二维数组,可以这样做:

>>> x = np.arange(100).reshape(10,10)   # x = array([[0, 1, 2,... 9], [10,..19],])
>>> next((i,j) for i, x_i in enumerate(x) 
...            for j, x_ij in enumerate(x_i) if x_ij == 2)
(0, 2)

这种方法的优点是它在找到第一个匹配后停止检查数组的元素,而np.where检查所有元素是否匹配。如果数组中的早期匹配,则生成器表达式会更快。

numpy_indexed 软件包(免责声明,我是它的作者)包含了vector.index的向量化等价物为numpy.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]

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

注意:这适用于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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top