Python 提取比numpy中的花式索引慢?

Python 提取比numpy中的花式索引慢?,python,numpy,Python,Numpy,Ndarray有一个成员函数extract,用于提取满足某些条件的数组元素。但是,此函数比花式索引慢。我们为什么要使用这个函数 from numpy import * a=random.random((1000,2000)) b=a>0.2 %timeit extract(b,a) %timeit a[b] %timeit extract(a>0.2,a) %timeit a[a>0.2] 以下是我的产出: In [138]: %timeit extract(b,a) 10

Ndarray
有一个成员函数
extract
,用于提取满足某些条件的数组元素。但是,此函数比花式索引慢。我们为什么要使用这个函数

from numpy import *
a=random.random((1000,2000))
b=a>0.2
%timeit extract(b,a)
%timeit a[b]
%timeit extract(a>0.2,a)
%timeit a[a>0.2]
以下是我的产出:

In [138]: %timeit extract(b,a)
10 loops, best of 3: 29.6 ms per loop

In [139]: %timeit a[b]
100 loops, best of 3: 18.5 ms per loop

In [140]: %timeit extract(a>0.2,a)
10 loops, best of 3: 31.4 ms per loop

In [141]: %timeit a[a>0.2]
10 loops, best of 3: 19.7 ms per loop

如果我们检查
np.extract
,我们会发现:

take(a.ravel(), nonzero(ravel(b))[0])
这里有趣的是,我们取
b
这是一个布尔数组,并将其转换为索引,以便正常的
np.take
操作可以像广告中那样工作。如果我们检查这需要多长时间,我们就会意识到
非零
占总时间的大部分,而奇特的索引所需时间少于
非零

%timeit nonzero(ravel(b))[0]
100 loops, best of 3: 13.1 ms per loop

%timeit take(a.ravel(), nonzero(ravel(b))[0])
100 loops, best of 3: 18.7 ms per loop

%timeit a[b]
100 loops, best of 3: 12.9 ms per loop

解释说,即使是花哨的索引也会使用某种
非零
类操作创建索引数组;然而,奇特的索引并不涉及python抽象层。我相信python抽象层是这里的关键。我不想猜测到底发生了什么,但我希望当函数完全在C端时会发生大量优化(就像所有花哨的索引一样)。

您使用哪个numpy版本?numpy 1.8 extract文档说:“如果
条件
是布尔的
np。extract
相当于
arr[condition]
”@Jan PhilipGehrcke在
np.take
和花式索引之间存在长期的时间差异,即使这两种操作是等效的-由于各种原因,时间变化并非不可能<代码>提取也基于“获取”。@Jan PhilipGehrcke我的numpy版本是1.8.0。所以我们说这些差异是无关紧要的,是因为测量不准确?或者换句话说:这不是正确的基准?@Jan PhilipGehrcke根据文档
extract
相当于
np.compress(ravel(condition),ravel(arr))
,它们花费了相同的时间。啊,这些文档在大多数索引方面都过时了。当形状完全匹配时,有一个专门的布尔索引路径。提取可能会被重写以使用它(尽管对于非布尔数组,非零逻辑可能更好)。@seberg很高兴知道,你介意指出源代码中奇特索引的位置吗?最近得到了所有不同的结果(不是布尔情况)。高级索引从这里开始简单的布尔型索引在前面处理过(非零也调用非简单型,它在prepare_index函数中)。了解花式索引是如何工作的不是在公园里散步,但是如果你需要帮助,请随时问我。