La clasificación numpy estructurada y las matrices de registro es muy lenta

Parece que la ordenación numérica estructurada y las matrices de grabación de una sola columna es mucho más lenta que hacer una ordenación en una matriz independiente similar:

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 

Hay una mejora marginal al usar la matriz estructurada, pero no es dramática:

 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 

Esto indica que es potencialmente más rápido crear una matriz de índice desde argsort y luego usarla para reordenar las matrices individuales. Esto está bien, excepto que espero tratar con arreglos muy grandes y me gustaría evitar copiar los datos tanto como sea posible. ¿Hay una forma más eficiente de hacer esto que me estoy perdiendo?

Como Jaime ha dicho, puedes usar argsort para ordenar la matriz de registros.

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

Y usa take para evitar hacer una copia.

 np.take(rec, inds, out=rec) 

Lo que te está ralentizando es el uso del order , no el hecho de que tengas una matriz de registros. Si quieres ordenar por un solo campo, hazlo así:

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

Una vez que se utiliza el order , el rendimiento va hacia el sur sin importar cuántos campos desee ordenar por:

 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