np.power
ist ein universal function (ufunc). Diese Funktionen können für Skalare und Arrays mit verschiedenen Datentypen verwendet werden, müssen jedoch zuerst den Typ der Eingabewerte überprüfen, damit sie bestimmen können, welche interne Schleife zum Generieren geeigneter Ausgabewerte verwendet werden soll.
Wenn die Eingabetypen keiner der vordefinierten Schleifen von ufunc zugeordnet sind, versucht ufunc cast the input values to suitable types (sofern nicht anders angegeben). Diese Überprüfung und Umwandlung von Eingabewerten hat einen damit verbundenen Leistungsaufwand, der die in der Frage beobachteten Zeitpunkte erklärt.
Das Attribut types
eines ufunc zeigt, wie Eingabedatentypen einem Ausgabedatentyp zugeordnet werden. Unten ist die Liste der Zuordnungen für np.power
:
>>> np.power.types # 'input input -> output'
['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q',
'QQ->Q', 'ee->e', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G', 'OO->O']
Gleitkommazahlen in Zeichencode gehören 'g'
, gehören Python ganzen Zahlen 'l'
. Eine vollständige Liste dieser Zeichencodes finden Sie unter here.
Beachten Sie, dass für diese ufunc die Datentypen der beiden Eingabewerte identisch sein müssen. Es gibt beispielsweise keine Zuordnung für eine Mischung aus float
und int
Eingabedatentypen.
Aber wir können immer verschiedene Datentypen geben und lassen Sie die Werte auf entsprechende Datentypen. Für ein float
und ein int
, eine float64
Zahl zurückgegeben:
>>> np.power(3.71242, 7).dtype
dtype('float64')
Above Sie, dass der einzige Eingang g
Karten zum float64
Zeichencode zu sehen, die g
Werte zwei andere ist: 'gg->g'
.
Also, hinter den Kulissen, nahm np.power(3.71242, 7)
eine Python float
und eine Python int
und zu entscheiden hatte, auf die sie sicher und welche Art neu zu fassen könnte. Der int
Wert wurde sicher zu einem Float-Typ g
heraufgestuft. Der ufunc wusste dann, welche Schleife ausgeführt werden sollte, und gab einen weiteren g
-Wert zurück.
Aus diesem Grund führt das Nicht-Mischen von Eingabe-Datentypen zu einer besseren Leistung für np.power
.
Wenn ich eine Vermutung wagen musste, erwartet numpy einen Float, erhielt aber einen int und musste konvertieren. –
@JeffMercado interessante Idee --- aber es scheint nicht ganz zu addieren: "% Zeit Zeit -n 100000 -r 10 if (type (2) == int): float (2)" ==> "100000 loops, best of 10: 571 ns pro Schleife " – DilithiumMatrix
Ich vermute, dass ein int-Exponent eine tatsächliche Multiplikation verursacht, während ein float-Exponent die Verwendung von Protokollen verursacht. –