vettore - prodotto vettori python




Il modo più efficiente per invertire una matrice numpy (4)

Che ci crediate o no, dopo aver profilato il mio codice attuale, l'operazione ripetitiva di reversione di array numpy ha mangiato un pezzo enorme del tempo di esecuzione. Quello che ho adesso è il comune metodo basato sulla vista:

reversed_arr = arr[::-1]

C'è un altro modo per farlo in modo più efficiente, o è solo un'illusione dalla mia ossessione per le prestazioni insensibili e insensibili?


Come accennato in precedenza, a[::-1] crea solo una vista, quindi è un'operazione a tempo costante (e come tale non richiede più tempo con la crescita dell'array). Se hai bisogno che l'array sia contiguo (ad esempio perché stai eseguendo molte operazioni vettoriali con esso), ascontiguousarray è veloce come flipup / fliplr :

Codice per generare 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(20)],
    xlabel='len(a)',
    logx=True,
    logy=True,
    )

Espanderò la risposta precedente su np.fliplr() . Ecco un codice che dimostra la costruzione di un array 1d, trasformandolo in un array 2D, ruotandolo, quindi convertendolo nuovamente in un array 1d. time.clock() verrà utilizzato per conservare il tempo, che viene presentato in termini di secondi.

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 la dichiarazione di stampa non commentata:

[2 1 0]
0.00203907123594

Con la dichiarazione di stampa commentata:

5.59799927506e-05

Quindi, in termini di efficienza, penso che sia decente. Per quelli di voi che amano farlo in una riga, ecco quella forma.

np.fliplr(np.atleast_2d(np.array(range(3))))[0]

Perché questo sembra non essere contrassegnato come risposta ancora ... La risposta di Thomas Arildsen dovrebbe essere quella giusta: basta usare

np.flipud(your_array) 

se è un array 1d (array di colonne).

Con le matrici fare

fliplr(matrix)

se vuoi invertire righe e flipud(matrix) se vuoi capovolgere le colonne. Non c'è bisogno di rendere il vostro array di colonne 1d un array di righe 2dimensionali (matrice con un layer None) e quindi capovolgerlo.


Quando crei reversed_arr stai creando una vista nell'array originale. È quindi possibile modificare l'array originale e la vista verrà aggiornata per riflettere le modifiche.

Stai ricreando la visualizzazione più spesso del necessario? Dovresti essere in grado di fare qualcosa del genere:

arr = np.array(some_sequence)
reversed_arr = arr[::-1]

do_something(arr)
look_at(reversed_arr)
do_something_else(arr)
look_at(reversed_arr)

Non sono un esperto di numpy, ma sembra che sarebbe il modo più veloce per fare le cose in numpy. Se questo è ciò che stai già facendo, non penso che tu possa migliorarlo.

PS Grande discussione su numpy views qui:

Visualizza su una matrice numpy?





numpy