¿Es numpy.transpose reordenar datos en la memoria?

Para acelerar las funciones como np.std, np.sum, etc. a lo largo de un eje de una matriz numpy de gran número, se recomienda aplicar a lo largo del último eje.

Cuando lo haga, np.transpose para rotar el eje que quiero operar, hasta el último eje. ¿Es realmente una reorganización de los datos en la memoria, o simplemente cambiando la forma en que se abordan los ejes?

Cuando traté de medir el tiempo usando% timeit. estaba haciendo esta transposición en microsegundos, (mucho más pequeño que el tiempo requerido para copiar la matriz (112x1024x1024) que estaba teniendo).

Si en realidad no está reordenando los datos en la memoria y solo cambiando el direccionamiento, ¿seguirá acelerando el np.sum o np.std cuando se aplique al último eje girado recientemente?

Cuando traté de medirlo, parece que se acelera. Pero no entiendo cómo.

Actualizar

Realmente no parece acelerar con la transposición. El eje más rápido es el último cuando está ordenado por C, y el primero cuando está ordenado por Fortran. Por lo tanto, no tiene sentido transponer antes de aplicar np.sum o np.std. Para mi código específico, resolví el problema dando orden = ‘FORTRAN’ durante la creación de la matriz. Lo que hizo el primer eje más rápido.

Gracias por todas las respuestas.

La transposición solo cambia los pasos , no toca la matriz real. Creo que la razón por la cual se recomienda la sum etc. a lo largo del eje final (me gustaría ver la fuente para eso, por cierto) es que cuando una matriz está ordenada por C, caminar a lo largo del eje final conserva la localidad de referencia. Ese no será el caso después de la transposición, ya que la matriz transpuesta será ordenada por Fortran.

Para profundizar en la respuesta de larsman, aquí hay algunos tiempos:

 # normal C (row-major) order array >>> %%timeit a = np.random.randn(500, 400) >>> np.sum(a, axis=1) 1000 loops, best of 3: 272 us per loop # transposing and summing along the first axis makes no real difference # to performance >>> %%timeit a = np.random.randn(500, 400) >>> np.sum(aT, axis=0) 1000 loops, best of 3: 269 us per loop # however, converting to Fortran (column-major) order does improve speed... >>> %%timeit a = np.asfortranarray(np.random.randn(500,400)) >>> np.sum(a, axis=1) 10000 loops, best of 3: 114 us per loop # ... but only if you don't count the conversion in the timed operations >>> %%timeit a = np.random.randn(500, 400) >>> np.sum(np.asfortranarray(a), axis=1) 1000 loops, best of 3: 599 us per loop 

En resumen, podría tener sentido convertir sus arreglos a la orden de Fortran si va a aplicar muchas operaciones sobre las columnas, pero la conversión en sí es costosa y casi con seguridad no vale la pena para una sola operación.