排序numpy结构化和记录数组非常慢

Rok*_*Rok 7 python arrays sorting numpy

看起来像单个列对numpy结构化和记录数组进行排序比在类似的独立数组上进行排序要慢得多:

In [111]: a = np.random.rand(1e4)

In [112]: b = np.random.rand(1e4)

In [113]: rec = np.rec.fromarrays([a,b])

In [114]: timeit rec.argsort(order='f0')
100 loops, best of 3: 18.8 ms per loop

In [115]: timeit a.argsort()
1000 loops, best of 3: 891 µs per loop
Run Code Online (Sandbox Code Playgroud)

使用结构化数组有一个微小的改进,但它不是戏剧性的:

In [120]: struct = np.empty(len(a),dtype=[('a','f8'),('b','f8')])

In [121]: struct['a'] = a

In [122]: struct['b'] = b

In [124]: timeit struct.argsort(order='a')
100 loops, best of 3: 15.8 ms per loop
Run Code Online (Sandbox Code Playgroud)

这表明从argsort创建索引数组然后使用它来重新排序各个数组可能会更快.这是可以的,除了我希望处理非常大的数组,并希望尽可能避免复制数据.有没有一种更有效的方法来做到这一点,我错过了?

ims*_*msc 3

正如 Jaime 所说,您可以使用argsort对记录数组进行排序。

inds = np.argsort(rec['f0'])
Run Code Online (Sandbox Code Playgroud)

并用于take避免复制

np.take(rec, inds, out=rec)
Run Code Online (Sandbox Code Playgroud)

  • 有效的唯一原因是因为当您指定“out”参数并将“mode”保留为其默认“raise”状态时,“np.take”会生成一份副本,您可以查看[源代码](https ://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/item_selection.c#L99)。如果您使用另一种“模式”,则不会有副本,但输出将是垃圾,某些值重复多次,而另一些值则完全丢失。 (2认同)