Numpy等效于list.index

lot*_*rio 18 python numpy

在一个被多次调用的低级函数中,我需要做相当于python的list.index,但是需要一个numpy数组.函数需要在找到第一个值时返回,否则引发ValueError.就像是:

>>> a = np.array([1, 2, 3])
>>> np_index(a, 1)
0
>>> np_index(a, 10)
Traceback (most recent call last):    
  File "<stdin>", line 1, in <module>
ValueError: 10 not in array
Run Code Online (Sandbox Code Playgroud)

我希望尽可能避免使用Python循环. np.where不是一个选项,因为它总是遍历整个数组; 一旦找到第一个索引,我需要停止的东西.


编辑:与问题相关的一些更具体的信息.

  • 大约90%的时间,我正在搜索的索引是阵列的前1/4到1/2.因此,这里可能存在2-4倍的加速因素.另外10%的时间值根本不在数组中.

  • 我已经分析了一些东西,并且调用np.where是瓶颈,至少占总运行时间的50%.

  • 提出一个并不重要ValueError; 它只需要返回一些显然表明该值不在数组中的东西.

我建议可能会在Cython中编写一个解决方案.

Jos*_*del 8

请参阅我对OP的问题的评论,但一般来说,我会做以下事情:

import numpy as np
a = np.array([1, 2, 3])
np.min(np.nonzero(a == 2)[0])
Run Code Online (Sandbox Code Playgroud)

如果您要查找的值不在数组中,您将得到以下内容ValueError:

ValueError: zero-size array to ufunc.reduce without identity
Run Code Online (Sandbox Code Playgroud)

因为你试图获取空数组的最小值.

我会分析这段代码并查看它是否是一个真正的瓶颈,因为通常当numpy使用内置函数而不是显式python循环搜索整个数组时,它相对较快.当发现第一个值时,坚持停止搜索可能在功能上无关紧要.


小智 6

如果你的 numpy 数组是一维数组,也许可以尝试这样:

a = np.array([1, 2, 3])
print a.tolist().index(2)
>>> 1
Run Code Online (Sandbox Code Playgroud)

如果不是 1d,您可以搜索数组,如下所示:

a = np.array([[1, 2, 3],[2,5,6],[0,0,2]])
print a[0,:].tolist().index(2)
>>> 1

print a[1,:].tolist().index(2)
>>> 0

print a[2,:].tolist().index(2)
>>> 2
Run Code Online (Sandbox Code Playgroud)


Joe*_*Joe 2

我能找到的最接近您要求的东西是非零。这可能听起来很奇怪,但文档让它看起来可能有预期的结果。

http://www.scipy.org/Numpy_Example_List_With_Doc#nonzero

具体这部分:

a.nonzero()

返回非零元素的索引。

请参阅numpy.nonzero完整文档。

也可以看看

numpy.nonzero :等效函数

>>> from numpy import *
>>> y = array([1,3,5,7])
>>> indices = (y >= 5).nonzero()
>>> y[indices]
array([5, 7])
>>> nonzero(y)                                # function also exists
(array([0, 1, 2, 3]),)
Run Code Online (Sandbox Code Playgroud)

其中 (http://www.scipy.org/Numpy_Example_List_With_Doc#where) 您可能也感兴趣。