La forma más eficiente de revertir una matriz numpy

Resuelto nye17 asked hace 13 años • 8 respuestas

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?

nye17 avatar Jul 21 '11 11:07 nye17
Aceptado
reversed_arr = arr[::-1]

ofrece una vista invertida de la matriz original arr. Cualquier cambio realizado en la matriz original arrtambién será visible inmediatamente en reversed_arr. Los buffers de datos subyacentes para arry reversed_arrson 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.

steveha avatar Jul 21 '2011 05:07 steveha
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), ascontiguousarrayes tan rápido como flipud/ fliplr:

ingrese la descripción de la imagen aquí


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)",
)
Nico Schlömer avatar Jul 05 '2017 08:07 Nico Schlömer