使用numpy记录数组进行索引非常缓慢。

4
看起来用索引数组对numpy记录数组进行索引非常慢。然而,同样的操作可以使用np.view快10-15倍。
这种差异背后的原因是什么?为什么没有以更快的方式实现记录数组的索引?(另请参见排序numpy结构化和记录数组非常缓慢
mydtype = np.dtype("i4,i8")
mydtype.names = ("foo","bar")
N = 100000

foobar = np.zeros(N,dtype = mydtype)
foobar["foo"] = np.random.randint(0,100,N)
foobar["bar"] = np.random.randint(0,10000,N)

b = np.lexsort((foobar["foo"],foobar["bar"]))

timeit foobar[b]
100 loops, best of 3: 11.2 ms per loop

timeit foobar.view("|S12")[b].view(mydtype)
1000 loops, best of 3: 882 µs per loop

显然,两个结果都给出了相同的答案。

也许是因为lexsort对数组进行排序,而view只是创建一个视图!?我认为这个问题也可以在http://codereview.stackexchange.com/上提问! - jkalden
在numpy的github上提出这个问题可能会更有成效。那些人知道如何处理numpy源代码。 - hpaulj
1个回答

3

take,如https://dev59.com/LnjZa4cB1Zd3GeqPfZHp#23303357所述,比您的双视图方法更快:

np.take(foobar,b)

实际上,它的速度和...一样快。
foobar['foo'][b]

https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/item_selection.c是深入研究源代码的起点。

我猜测,实现__getitem__的某些细节导致了这种差异。也许作为早期记录处理的遗留问题,在dtype混合(和高级索引)时它会采取不同的路径。

布尔掩码索引似乎不受此减速影响。基本的切片索引也一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接