La forma más eficiente de revertir una matriz numpy
Lo creas o no, después de perfilar mi código actual, la operación repetitiva de reversión de matrices numpy consumió una gran parte del tiempo de ejecución. Lo que tengo ahora es el método común basado en vistas:
reversed_arr = arr[::-1]
¿Hay alguna otra manera de hacerlo de manera más eficiente, o es solo una ilusión de mi obsesión por el desempeño poco realista?
reversed_arr = arr[::-1]
ofrece una vista invertida de la matriz original arr
. Cualquier cambio realizado en la matriz original arr
también será visible inmediatamente en reversed_arr
. Los buffers de datos subyacentes para arr
y reversed_arr
son compartidos , por lo que la creación de esta vista siempre es instantánea y no requiere ninguna asignación de memoria adicional ni copia del contenido de la matriz.
Consulte también esta discusión sobre vistas NumPy: ¿ Cómo creo una vista en una matriz NumPy?
Posibles soluciones a problemas de rendimiento con respecto a las vistas.
¿Está recreando la vista con más frecuencia de la necesaria? Deberías poder hacer algo como esto:
arr = np.array(some_sequence)
reversed_arr = arr[::-1]
do_something(arr)
look_at(reversed_arr)
do_something_else(arr)
look_at(reversed_arr)
No soy un experto en numpy, pero parece que sería la forma más rápida de hacer cosas en numpy. Si esto es lo que ya estás haciendo, no creo que puedas mejorarlo.
a[::-1]
solo crea una vista, por lo que es una operación de tiempo constante (y como tal, no lleva más tiempo a medida que crece la matriz). Si necesita que la matriz sea contigua (por ejemplo, porque está realizando muchas operaciones vectoriales con ella), ascontiguousarray
es tan rápido como flipud
/ fliplr
:
Código para generar la trama:
import numpy
import perfplot
perfplot.show(
setup=lambda n: numpy.random.randint(0, 1000, n),
kernels=[
lambda a: a[::-1],
lambda a: numpy.ascontiguousarray(a[::-1]),
lambda a: numpy.fliplr([a])[0],
],
labels=["a[::-1]", "ascontiguousarray(a[::-1])", "fliplr"],
n_range=[2 ** k for k in range(25)],
xlabel="len(a)",
)