python - matriz - numpy functions
La forma más eficiente de revertir una matriz numpy (6)
Créalo o no, después de perfilar mi código actual, la operación repetitiva de la reversión de la matriz numpy se comió 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 forma de hacerlo de manera más eficiente, o es solo una ilusión de mi obsesión con el rendimiento de números poco realistas?
Como se mencionó anteriormente, a[::-1]
realmente solo crea una vista, por lo que es una operación de tiempo constante (y como tal no toma más tiempo a medida que la matriz crece). Si necesita que la matriz sea contigua (por ejemplo, porque está realizando muchas operaciones vectoriales con ella), ascontiguousarray
es casi tan rápido como flipup
/ 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)'',
logx=True,
logy=True,
)
Cuando crea reversed_arr
está creando una vista en la matriz original. Luego puede cambiar la matriz original y la vista se actualizará para reflejar los cambios.
¿Está recreando la vista con más frecuencia de la que necesita? 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 las cosas en numpy. Si esto es lo que ya estás haciendo, no creo que puedas mejorarlo.
PD Gran discusión de vistas numpy aquí:
Debido a que esto parece no estar marcado como contestado todavía ... La Respuesta de Thomas Arildsen debería ser la correcta: solo use
np.flipud(your_array)
si es una matriz 1d (matriz de columnas).
Con matrizes hacer
fliplr(matrix)
si desea revertir filas y flipud(matrix)
si desea voltear columnas. No es necesario convertir su matriz de columnas 1d en una matriz de filas bidimensionales (matriz con una capa Ninguna) y luego voltearla.
Para que funcione con números negativos y una lista larga, puede hacer lo siguiente:
b = numpy.flipud(numpy.array(a.split(),float))
Donde flipud es para arra 1d
np.fliplr()
respuesta anterior sobre np.fliplr()
. Aquí hay un código que muestra cómo construir una matriz 1d, transformarla en una matriz 2d, voltearla y convertirla de nuevo en una matriz 1d. time.clock()
se utilizará para mantener la hora, que se presenta en términos de segundos.
import time
import numpy as np
start = time.clock()
x = np.array(range(3))
#transform to 2d
x = np.atleast_2d(x)
#flip array
x = np.fliplr(x)
#take first (and only) element
x = x[0]
#print x
end = time.clock()
print end-start
Con declaración impresa sin comentarios:
[2 1 0]
0.00203907123594
Con la declaración impresa comentada:
5.59799927506e-05
Entonces, en términos de eficiencia, creo que eso es decente. Para aquellos de ustedes que aman hacerlo en una línea, aquí está esa forma.
np.fliplr(np.atleast_2d(np.array(range(3))))[0]
np.fliplr()
voltea la matriz de izquierda a derecha.
Tenga en cuenta que para las matrices 1d, necesita engañarlo un poco:
arr1d = np.array(some_sequence)
reversed_arr = np.fliplr([arr1d])[0]