2012-04-28 16 views
6

Ho un array:Ottenere somme di coppie di elementi in una matrice NumPy

t = [4, 5, 0, 7, 1, 6, 8, 3, 2, 9] 

che è solo un riordino casuale nell'intervallo [0, 9]. Ho bisogno di calcolare questo:

t2 = [9, 5, 7, 8, 7, 14, 11, 5, 11, 13] 

che è solo:

t2 = [t[0]+t[1], t[1]+t[2], t[2]+t[3], t[3]+t[4], ..., t[9]+t[0]] 

C'è un modo che io possa fare questo con NumPy per evitare un pitone ciclo for quando si tratta di grandi array?

risposta

18

Si potrebbe sfruttare la capacità di un array di NumPy per riassumere elemento-saggio:

In [5]: import numpy as np 

In [6]: t = np.array([4, 5, 0, 7, 1, 6, 8, 3, 2, 9]) 

In [7]: t + np.r_[t[1:],t[0]] 
Out[7]: array([ 9, 5, 7, 8, 7, 14, 11, 5, 11, 13]) 

np.r_ è un modo per concatenare le sequenze insieme per formare un nuovo array NumPy. Come vedremo di seguito, non risulta essere il modo migliore in questo caso.


Un'altra possibilità è:

In [10]: t + np.roll(t,-1) 
Out[10]: array([ 9, 5, 7, 8, 7, 14, 11, 5, 11, 13]) 

Appare utilizzando np.roll è significativamente più veloce:

In [11]: timeit t + np.roll(t,-1) 
100000 loops, best of 3: 17.2 us per loop 

In [12]: timeit t + np.r_[t[1:],t[0]] 
10000 loops, best of 3: 35.5 us per loop 
+0

Dovuto a Google cosa 'np.r_' fa :) Potresti aggiungere il link e una breve spiegazione alla risposta? – ovgolovin

+0

@ovgolovin: done! – unutbu

1

È possibile farlo abbastanza felicemente con zip(), una fetta lista, e a list comprehension:

t2 = [a+b for (a, b) in zip(t, t[1:])] 
t2.append(t[0]+t[-1]) 

abbiamo bisogno del più append() per aggiungere l'ultimo elemento, come zip() funziona solo fino a quando l'iteratore più breve termine. Una comprensione delle liste è significativamente più veloce di un normale ciclo for poiché implementa il lato C in Python, piuttosto che come un loop Python.

L'alternativa è quella di utilizzare itertools.zip_longest:.

from itertools import zip_longest 
t2 = [a+b for (a, b) in zip_longest(t, t[1:], fillvalue=t[0])] 

Per riempire il valore aggiunto in Do atto che questa funzione è itertools.izip_longest in Python 2.x.

+0

L'autore ha chiesto specificamente di risolvere l'attività ** con numpy ** per evitare l'overhead del loop Python. – ovgolovin

+3

@ovgolovin No, ha chiesto di evitare un loop python e una comprensione delle liste è fatta come un ciclo in C all'interno di Python. Ciò significa che è significativamente più veloce di un ciclo normale. –

+3

Sarà ancora incredibilmente subottimale rispetto alle operazioni vettoriali di Numpy. –

1

Che dire

import numpy as np 
t = np.array([4, 5, 0, 7, 1, 6, 8, 3, 2, 9]) 

new_t = t + np.hstack((t[1:], [t[0]])) 

Risultato:

>>> new_t 
array([ 9, 5, 7, 8, 7, 14, 11, 5, 11, 13]) 
+0

+1 per un'altra soluzione, sebbene sia un po 'più lenta della risposta accettata. – amillerrhodes

Problemi correlati