Python-Summe vs. NumPy ist numpy.Summe
Was sind die Unterschiede in Leistung und Verhalten zwischen der Verwendung von Python-native sum
Funktion und NumPy ist numpy.sum
? sum
funktioniert auf NumPy - arrays und numpy.sum
funktioniert auf Python-Listen und Sie beide wieder den gleichen effektiven Ergebnis (noch nicht getestet Rand Fälle wie überlauf), aber unterschiedliche Typen.
>>> import numpy as np
>>> np_a = np.array(range(5))
>>> np_a
array([0, 1, 2, 3, 4])
>>> type(np_a)
<class 'numpy.ndarray')
>>> py_a = list(range(5))
>>> py_a
[0, 1, 2, 3, 4]
>>> type(py_a)
<class 'list'>
# The numerical answer (10) is the same for the following sums:
>>> type(np.sum(np_a))
<class 'numpy.int32'>
>>> type(sum(np_a))
<class 'numpy.int32'>
>>> type(np.sum(py_a))
<class 'numpy.int32'>
>>> type(sum(py_a))
<class 'int'>
Edit: ich glaube, meine praktische Frage ist hier, würde mit numpy.sum
auf einer Liste von Python-Ganzzahlen schneller als mit Python eigene sum
?
Außerdem, was sind die Auswirkungen (einschließlich Leistung), der mit einer Python integer Vergleich zu einem Skalar numpy.int32
? Zum Beispiel, für a += 1
ist es ein Verhalten oder Leistung der Unterschied, wenn die Art der a
ist ein in Python integer-oder eine numpy.int32
? Ich bin gespannt, ob es schneller ist, verwenden Sie ein NumPy skalaren Datentyp wie numpy.int32
für einen Wert, der addiert oder subtrahiert werden, eine Menge in Python-code.
Zur Klarstellung, ich arbeite an einem Bioinformatik-simulation, die teilweise aus der einstürzenden mehrdimensionale numpy.ndarray
s in einzelnen skalaren Summen, die dann zusätzlich verarbeitet. Ich bin mit Python 3.2 und NumPy 1.6.
Vielen Dank im Voraus!
InformationsquelleAutor der Frage Sumant Manne | 2012-06-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich wurde neugierig und zeitlich.
numpy.sum
scheint viel schneller bei numpy-arrays, aber viel langsamer auf der Liste.Ergebnis, wenn
x = range(1000)
:Ergebnis, wenn
x = np.random.standard_normal(1000)
:Ich bin mit Python 2.7.2 und Numpy 1.6.1
InformationsquelleAutor der Antwort Akavall
Numpy sollte viel schneller sein, vor allem, wenn Ihre Daten bereits in ein numpy-array.
Numpy-arrays sind eine dünne Schicht über eine standard-C-array. Wenn numpy Summe iteriert über diese, die es nicht tun, die überprüfung von Typ und es ist sehr schnell. Die Geschwindigkeit sollte vergleichbar sein zu tun, den Betrieb mit standard-C.
Im Vergleich mit python Summe muss es zuerst konvertieren Sie die numpy-Arrays in ein python-array und iteriere über das array. Es hat damit zu tun, irgendeine Art der überprüfung und ist in der Regel gehen langsamer.
Den genauen Betrag, den python-Summe ist langsamer als numpy Summe ist nicht gut definiert, wie der python-Summe ist eine etwas optimierte Funktion im Vergleich zum schreiben einer eigenen Funktion sum in python.
InformationsquelleAutor der Antwort Claris
Die Antwort auf diese Frage ist: Nein.
Pythons Summe wird schneller auf Listen, während NumPys Summe sein wird, schneller auf-arrays. Eigentlich wollte ich einen benchmark, um zu zeigen, die timings (Python-3.6, NumPy 1.14):
Mit diesen Ergebnissen:
Links: auf ein NumPy-array; Rechts: auf einer Python-Liste.
Hinweis: dies ist eine log-log-plot, da der benchmark deckt ein sehr breites Spektrum von Werten. Aber für qualitative Ergebnisse: Niedriger bedeutet bessere.
Welche zeigt, dass in den Listen Pythons
sum
ist immer schneller, währendnp.sum
oder diesum
- Methode auf das array schneller sein (außer für sehr kurze arrays, wo Pythonssum
ist schneller).Nur für den Fall Sie interessiert sind, vergleichen diese mit einander, ich habe auch einen plot einschließlich aller von Ihnen:
Interessanterweise der Punkt, an dem
numpy
konkurrieren können arrays mit Python und Listen ist etwa bei rund 200 Elemente! Beachten Sie, dass diese Zahl hängt von einer Vielzahl von Faktoren, wie z.B. Python/NumPy-version, ... nimm es nicht zu wörtlich.Was noch nicht erwähnt wurde ist der Grund für diesen Unterschied (ich meine die großen Skala Unterschied nicht den Unterschied für kurze Listen/arrays, wo die Funktionen haben einfach verschiedene Konstante overhead). Vorausgesetzt, CPython eine Python-Liste ist ein wrapper um ein C (in der Sprache C) array von Zeiger auf Python Objekte (in diesem Fall Python-Ganzzahlen). Diese ganzen zahlen gesehen werden kann, die als Wrapper um eine C-Ganzzahl (eigentlich nicht korrekt, weil Python die ganzen zahlen können beliebig groß, so dass es nicht einfach eine C integer, aber es ist nah genug).
Zum Beispiel eine Liste wie
[1, 2, 3]
wäre (schematisch, ließ ich ein paar details) wie folgt gespeichert:Einen NumPy-array jedoch ist ein wrapper um ein C-array mit C-Werte (in diesem Fall
int
oderlong
je nach 32 oder 64bit und je nach Betriebssystem).So ein NumPy-array wie
np.array([1, 2, 3])
würde wie folgt Aussehen:Das nächste, was zu verstehen ist, wie diese Funktionen arbeiten:
sum
durchläuft die iterierbar (in diesem Fall die Liste oder array) auf und fügt alle Elemente.sum
Methode iteriert über die gespeicherten C-array und fügt diese C-Werte und schließlich umschließt, den Wert in einem Python-Typ (in diesem Fallnumpy.int32
(odernumpy.int64
) und gibt es zurück.sum
Funktion wandelt die Eingabe in einenarray
(zumindest wenn es nicht ein array bereits), und dann verwendet das NumPysum
Methode.Klar das hinzufügen von C-Werte von a-C-array ist wesentlich schneller als das hinzufügen von Python-Objekten, weshalb die NumPy-Funktionen kann viel schneller (siehe den zweiten plot vor, der NumPy-Funktionen auf arrays, schlagen die Python-Summe bei weitem für große arrays).
Aber die Umwandlung einer Python-Liste in ein NumPy-array ist relativ langsam und dann noch die C Werte. Das ist der Grund, warum für Listen die Python
sum
schneller sein wird.Die einzige Verbleibende offene Frage ist, warum ist Pythons
sum
auf einearray
so langsam (es ist das langsamste von allen verglichenen Funktionen). Und tatsächlich hat mit der Tatsache zu tun, dass Pythons Summe einfach durchläuft, was auch immer Sie übergeben. Im Falle einer Liste wird es die gespeicherten Python-Objekt aber im Falle eines 1D-NumPy-array gibt es keine gespeicherten Python-Objekte, C-Werte, so dass Python&NumPy haben, erstellen Sie ein Python-Objekt (einenumpy.int32
odernumpy.int64
) für jedes element und dann diese Python-Objekte Hinzugefügt werden müssen. Die Erstellung der wrapper der C-Wert ist, was macht es wirklich langsam.Machte ich einige tests und für die addition und Subtraktionen von skalaren sollte man auf jeden Fall-stick mit Python-Ganzzahlen. Obwohl es könnte einige caching geht, was bedeutet, dass die folgenden tests vielleicht nicht ganz repräsentativ:
Es ist 3-6 mal schneller Skalare Operationen mit Python-Ganzzahlen als mit NumPy-Skalare. Ich habe nicht geprüft, warum das der Fall ist, aber meine Vermutung ist, dass NumPy Skalare sind selten benutzt und ist wohl nicht für die Leistung optimiert.
Den Unterschied wird ein bisschen weniger, wenn Sie tatsächlich führen Sie arithmetische Operationen aus, wo beide Operanden numpy skalaren:
Dann sind es nur noch 2 mal langsamer.
Falls Sie sich gefragt, warum ich verwendet
itertools.repeat
hier, wenn ich könnte einfach verwendetfor _ in range(...)
statt. Der Grund dafür ist, dassrepeat
ist schneller und daher verursacht weniger Aufwand pro Schleife. Denn ich bin nur daran interessiert, die addition/Subtraktion der Zeit ist es tatsächlich besser, nicht zu haben, die looping-overhead messing mit den timings (zumindest nicht viel).InformationsquelleAutor der Antwort MSeifert
Beachten Sie, dass Python Summe auf mehrdimensionale numpy-arrays wird nur dann ausgeführt werden, eine Summe, die entlang der ersten Achse:
InformationsquelleAutor der Antwort MichaelSB
Dies ist eine Erweiterung, die die Antwort Beitrag oben von Akavall. Aus dieser Antwort kann man sehen, dass
np.sum
führt schneller zumnp.array
Objekte, in der Erwägung, dasssum
führt schneller zumlist
Objekte. Ausbauen:Läuft auf
np.sum
für einenp.array
Objekt Vs.sum
für einelist
Objekt, scheint es, dass Sie durchführen, Hals an Hals.Oben
sum
ist ein winzigen bisschen schneller alsnp.array
obwohl, bei der ich mal gesehen habenp.sum
timings zu14.1 µs
auch. Aber meistens ist es14.3 µs
.InformationsquelleAutor der Antwort xyres