Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 与list.index等价的Numpy_Python_Numpy - Fatal编程技术网

Python 与list.index等价的Numpy

Python 与list.index等价的Numpy,python,numpy,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>",

在一个被多次调用的低级函数中,我需要执行与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
>a=np.array([1,2,3])
>>>np_指数(a,1)
0
>>>np_指数(a,10)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ValueError:10不在数组中
我希望尽可能避免Python循环
np。其中
不是一个选项,因为它总是遍历整个数组;我需要一个一旦找到第一个索引就停止的东西


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

  • 大约90%的时候,我搜索的索引位于数组的前1/4到1/2。所以这里有一个潜在的2-4加速因子。其他10%的时间该值根本不在数组中

  • 我已经分析过了,对
    np的调用是瓶颈,
    至少占据了总运行时间的50%

  • 它不一定会引发
    值错误
    ;它只需要返回一些明显指示该值不在数组中的内容


我可能会按照建议用Cython编写一个解决方案。

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

具体而言,本部分:

a、 非零()

返回非零元素的索引

有关完整文档,请参阅
numpy.nonzero

另见 numpy.nonzero:等价函数


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

有关注意事项,请参阅我对OP问题的评论,但一般来说,我会做以下几点:

import numpy as np
a = np.array([1, 2, 3])
np.min(np.nonzero(a == 2)[0])
如果您要查找的值不在数组中,您将得到一个
ValueError
,原因是:

ValueError: zero-size array to ufunc.reduce without identity
因为您试图获取空数组的最小值

我将分析这段代码,看看它是否是一个实际的瓶颈,因为通常当numpy使用内置函数而不是显式python循环搜索整个数组时,它的速度相对较快。在发现第一个值时坚持停止搜索可能在功能上不相关

NumPy的索引与list的索引非常相似,不同之处在于它需要一个排序数组,并且其行为更符合数字。最大的区别在于不需要精确匹配,可以从左侧或右侧开始搜索。请参见以下示例了解其工作原理:

import numpy as np
a = np.array([10, 20, 30])

a.searchsorted(-99) == a.searchsorted(0) == a.searchsorted(10)
# returns index 0 for value 10

a.searchsorted(20.1) == a.searchsorted(29.9) == a.searchsorted(30)
# returns index 2 for value 30

a.searchsorted(30.1) == a.searchsorted(99) == a.searchsorted(np.nan)
# returns index 3 for undefined value

对于最后一种情况,返回的索引为3,您可以随意处理。我从函数的名称和意图推断,在找到第一个合适的索引后,函数将停止。

您可以用Cython对其进行编码,然后从Python脚本导入。没有必要将整个项目迁移到Cython中

# paste into: indexing.pyx
def index(long[:] lst, long value):
    cdef int i
    for i in range(len(lst)):
        if lst[i] == value:
            return i
    raise ValueError

# import in your .py code
import pyximport
pyximport.install()
from indexing import index

# example
from numpy import zeros
a = zeros(10**6, int)
a[-1] = 1

index(a, 1)
Wall time: 6.07 ms
999999

index(a, 0)
Wall time: 38.1 µs
0

我唯一一次遇到这个问题时,将numpy数组强制转换为列表就足够了:

a = numpy.arange(3)
print(list(a).index(2))

>>> 2

如果您的numpy阵列是1d阵列,请尝试以下操作:

a = np.array([1, 2, 3])
print a.tolist().index(2)
>>> 1
如果不是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

那么你有一个numpy数组还是什么?是的;我对问题进行了编辑以澄清问题。您是否对代码进行了分析,以便您真正知道
哪里是瓶颈。您可以显示代码的该部分。您要查找的AFAIK功能在
numpy
中不存在。谢谢,我同意@eat。我认为numpy中没有一种方法可以满足您的要求,尤其是返回
ValueError
。如果您想避免python循环,我建议您应该在
cython
中编写自己的函数,这应该是快速的,并且完全按照您的要求执行。我也同意你应该分析你的代码,使用
nonzero
where
然后找到
min
索引实际上是你代码中的瓶颈。相反,如果您多次调用该函数,那么问题应该是您是否可以在单个数组操作可能工作时使用numpy来避免多次调用。在
numpy
中的
where
matlab中的
find
中,我从未遇到过任何严重的性能问题。(虽然有时简单的
逻辑索引
就足以胜任这项工作)我不会期望从
cython
中得到任何重大改进,除非你能想出一个非常具体的解决方案(视情况而定)。但是,您是否愿意向我们展示您当前的瓶颈代码?谢谢,但是
y>=5
nonzero(y)
命中了每个数组元素——我正在寻找一个函数,它在找到第一个索引后立即返回。这是正确的,如果你使用
np.nonzero(y==index\u值)[0][0]
它似乎在复制一个numpy数组的
y.index(index\u值)
,虽然我还没有对它进行广泛的测试,但我不知道它是否可以这样使用。它依赖于二进制搜索,OP没有指定他的数组已经排序。list.index依赖于排序数组,文档中的“二进制搜索”部分只是对那些混合数据类型(即,
a=np.array([2.1,3.1,4.1],dtype=np.float16);a.searchsorted(np.float32(3.1))的警告
返回2,而不是预期的1)list.index不依赖排序数组。哦,对了,list.index返回第一个索引(如果有)。是的,此解决方案仅适用于排序数组。
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