2012-04-28 15 views
6

Ich habe ein Array:Erhalten Summen von Paaren von Elementen in einem Array numpy

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

, die nur eine zufällige Shuffle des Bereichs [0, 9]. Ich brauche dies zu berechnen:

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

das ist nur:

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

Gibt es eine Weise, die ich dies mit numpy tun kann, eine Python for-Schleife zu vermeiden, wenn mit großen Arrays zu tun?

Antwort

18

Sie könnten nutzen die Fähigkeit des NumPy Feldelement weise zusammenzufassen:

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_ ist eine Möglichkeit, Sequenzen verketten gemeinsam eine neue numpy Array zu bilden. Wie wir unten sehen werden, stellt es sich heraus, nicht der beste Weg in diesem Fall.


Eine andere Möglichkeit ist:

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

Es np.roll mit erscheint deutlich schneller ist:

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

Hatte Google, was "np.r_" tut :) Könnten Sie den Link und eine kurze Erklärung der Antwort hinzufügen? – ovgolovin

+0

@ovgolovin: fertig! – unutbu

1

Sie können dies tun, ziemlich glücklich mit zip(), eine Liste in Scheiben schneiden, und a list comprehension:

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

Wir brauchen die zusätzlichen append() in dem letzten Element hinzuzufügen, wie zip() funktioniert nur, bis die kürzeste Iterator endet. Ein Listenverständnis ist wesentlich schneller als eine normale for-Schleife, da es in Python als C-Seite implementiert ist und nicht als Python-Schleife.

Die Alternative ist die Verwendung itertools.zip_longest.

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

Um den Mehrwert in füllen Sie beachten Sie, dass diese Funktion itertools.izip_longest in Python 2.x ist

+0

Der Autor speziell gebeten, die Aufgabe ** mit numpy ** zu lösen, um Python-Schleife Overhead zu vermeiden. – ovgolovin

+3

@ovgolovin Nein, er bat darum, eine Pythonschleife zu vermeiden, und ein Listenverständnis wird als Schleife in C innerhalb von Python ausgeführt. Dies bedeutet, dass es wesentlich schneller ist als eine normale Schleife. –

+3

Es wird immer noch unglaublich suboptimal im Vergleich zu Numpy Vektor-Operationen. –

1

Was

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]])) 

Ergebnis:

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

+1 für eine andere Lösung, obwohl es ein wenig langsamer als die angenommene Antwort ist. – amillerrhodes

Verwandte Themen