Stavo rivisitare alcuni dei miei codice per migliorare le prestazioni e stumpled sopra qualcosa di strano:Wrapping np.arrays __pow__ metodo
a = np.linspace(10,1000,1000000).reshape(1000,1000)
%timeit np.square(a)
100 loops, best of 3: 8.07 ms per loop
%timeit a*a
100 loops, best of 3: 8.18 ms per loop
%timeit a**2
100 loops, best of 3: 8.32 ms per loop
Ok sembra avere un certo overhead quando si utilizza il potere-operator (**
) ma per il resto sembrano identici (immagino NumPy sta facendo), ma poi ha ottenuto strano:
In [46]: %timeit np.power(a, 2)
10 loops, best of 3: 121 ms per loop
quindi non c'è nessun problema, ma sembra un po 'incoerente per avere un ripiego per il pow magia, ma non per l'UFUNC . Ma poi mi sono interessato da quando sto usando terze potenze molto:
%timeit a*a*a
100 loops, best of 3: 18.1 ms per loop
%timeit a**3
10 loops, best of 3: 121 ms per loop
%timeit np.power(a, 3)
10 loops, best of 3: 121 ms per loop
Non sembra esserci alcuna "scorciatoia" nella terza potenza e UFUNC e 'magic-pow' lavorare lo stesso (almeno per quanto riguarda prestazione).
Ma questo non è il massimo dal momento che voglio un metodo coerente di utilizzare i poteri nel mio codice e non sono abbastanza sicuro di come avvolgere il numero __pow__
di numpy.
Quindi, per arrivare al punto, la mia domanda è:
C'è un modo per avvolgere i numpys __pow__
metodo? Perché voglio un modo coerente di scrivere poteri nel mio script non scrivendo a**2
e in un altro posto power(a, 3)
. Semplicemente scrivendo a**3
e reindirizzando questo alla mia funzione di alimentazione, sarebbe preferibile (ma per quello avrei bisogno di avvolgere in qualche modo il ndarrays __pow__
o?). Attualmente sto usando una scorciatoia, ma questo non è che bello (ho nemmeno bisogno di dichiarare il == 2 caso esponente poiché np.power
esegue non ottimale lì):
def power(array, exponent):
if exponent == 2: #catch this, or it calls the slow np.power(array, exponent)
return np.square(array)
if exponent == 3:
return array * array * array
#As soon as np.cbrt is avaiable catch the exponent 4/3 here too
return np.power(array, exponent)
%timeit power(a, 3)
100 loops, best of 3: 17.8 ms per loop
%timeit a**3
10 loops, best of 3: 121 ms per loop
Sto usando NumPy v1.9.3 e non lo faccio desidera sottoclasse np.ndarray
solo per il wrapping del metodo __pow__
. :-)
EDIT: ho riscritto la parte in cui arrivo alla mia domanda. Per chiarirlo: non sto chiedendo perché NumPy lo fa nel modo in cui lo fa - questo è solo per spiegare perché io pongo la domanda.
Vuoi veramente ottimizzare l'operatore di potenza per il case quadrato perché è un po 'più veloce? Mi sembra davvero troppo ottimizzato; soprattutto se significa introdurre un'altra funzione. Basta usare '** n' tutto il tempo, e non preoccuparti di quella piccola differenza di fuso orario – poke
np.all (a ** 3 - a \ * a \ * a < 1e-6) -> Vero, quindi penso che sia lo stesso, per intorpidirti devo dichiararlo una matrice per innescare la moltiplicazione della matrice e sì la domanda è come avvolgere \ _ \ _ pow__ e la differenza di tempo è grande nel mio caso da quando mi occupo di molti di quegli array veramente grandi (1000 immagini 1000x2000). per le modifiche, sono abbastanza nuovo e non ottengo la formattazione del testo corretta – MSeifert
Non è possibile modificare il metodo '__pow__' di un narray senza usare sottoclassi. Potresti (come hai suggerito) scrivere un'altra funzione. Se sei preoccupato per le prestazioni, potresti usare una libreria come [numexpr] (https://github.com/pydata/numexpr) che ha una funzione di potenza ottimizzata. Ad esempio, 'numexpr.evaluate (" a ** 3 ")' è circa 20 volte più veloce di 'a * a * a'. –