8

看起来,按单列对 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

使用结构化数组有边际改进,但并不显着:

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

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

4

2 回答 2

4

拖慢你的是使用order,而不是你有一个记录数组的事实。如果要按单个字段排序,请执行以下操作:

In [12]: %timeit np.argsort(rec['f0'])
1000 loops, best of 3: 829 us per loop

一旦order使用,无论您要按多少个字段进行排序,性能都会下降:

In [16]: %timeit np.argsort(rec, order=['f0'])
10 loops, best of 3: 27.9 ms per loop

In [17]: %timeit np.argsort(rec, order=['f0', 'f1'])
10 loops, best of 3: 28.4 ms per loop
于 2013-10-30T16:26:50.880 回答
3

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

inds = np.argsort(rec['f0'])

并用于take避免复制

np.take(rec, inds, out=rec)
于 2014-04-25T21:27:08.000 回答