【问题标题】:Indexing numpy record arrays is very slow索引 numpy 记录数组非常慢
【发布时间】:2015-02-23 22:10:54
【问题描述】:

看起来用索引数组索引 numpy 记录数组非常慢。但是,使用np.view 执行相同的操作可以快10-15 倍。

这种差异背后有什么原因吗?为什么不以更快的方式实现记录数组的索引? (另见sorting numpy structured and record arrays is very slow

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 只是创建一个视图!?我觉得这个问题也可以在codereview.stackexchange.com问!
  • 在 numpy github 上提出这个问题可能会更有成效。这些人对 numpy 源代码了如指掌。

标签: performance numpy


【解决方案1】:

take,正如https://stackoverflow.com/a/23303357/901925 中提到的,甚至比你的双视图方法更快:

np.take(foobar,b)

事实上它和它一样快

foobar['foo'][b]

https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/item_selection.c 是您想要深入了解源代码的起点。

我的猜测是__getitem__ 的实现方式会导致这种差异。也许作为早期记录处理的残余,当dtype 混合时(以及用于高级索引),它会采用不同的路径。

布尔掩码索引似乎不受这种减速的影响。基本切片索引也是如此。

【讨论】:

    猜你喜欢
    • 2013-11-10
    • 2011-08-11
    • 2016-11-10
    • 2019-03-13
    • 1970-01-01
    • 2022-10-24
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多