6.8. Operatoren¶
Die erste Art von Mathematik, die numpy auf einem ndarray ausführt, sind die Standard-Python-Operatoren. Arithmetische, Vergleichs- und bitweise Operatoren arbeiten allesamt elementweise – jeder Operator durchläuft das Array (oder beide Arrays) einmal von Anfang bis Ende innerhalb eines einzigen Bibliotheksaufrufs, viel schneller als die entsprechende Python-for-Schleife.
6.8.1. Arithmetik¶
+, -, *, /, //, %, ** funktionieren alle zwischen zwei Arrays kompatibler Form oder zwischen einem Array und einem Skalar:
a = np.array([1, 2, 3, 4], dtype=np.float)
b = np.array([10, 20, 30, 40], dtype=np.float)
print(a + b) # array([11.0, 22.0, 33.0, 44.0])
print(a * 2) # array([2.0, 4.0, 6.0, 8.0])
print(b - a) # array([9.0, 18.0, 27.0, 36.0])
print(b / a) # array([10.0, 10.0, 10.0, 10.0])
Der dtype des Ergebnisses folgt den Aufwärtskonvertierungsregeln, die in Dtypes beschrieben sind. Ganzzahl-Arrays laufen bei Überlauf um; konvertieren Sie vor der Operation in einen breiteren dtype, wenn das wichtig ist.
Der Matrixmultiplikationsoperator @ ist nicht implementiert. Verwenden Sie dot() für Matrix-/Vektorprodukte.
6.8.1.1. In-place-Formen¶
Jeder arithmetische Operator hat eine In-place-Form – +=, -=, *=, /=, %=, **=. Die In-place-Form schreibt durch den bestehenden Puffer, anstatt ein temporäres Objekt zu reservieren:
b = b + 1 # allocates a temporary the size of b
b += 1 # no temporary
Auf einem Mikrocontroller ist die zweite Form für jede heiße Schleife im Grunde zwingend erforderlich.
6.8.2. Bitweise¶
Die bitweisen Operatoren &, |, ^ arbeiten elementweise auf Ganzzahl-Arrays. Auf ein float- oder complex-Array angewendet, lösen sie einen TypeError aus:
a = np.array([0b1100, 0b1010], dtype=np.uint8)
b = np.array([0b1010, 0b1100], dtype=np.uint8)
print(a & b) # array([8, 8], dtype=uint8)
print(a | b) # array([14, 14], dtype=uint8)
print(a ^ b) # array([6, 6], dtype=uint8)
Das unäre ~ führt ein bitweises NOT auf einem Ganzzahl-Array aus.
Die Schiebeoperatoren << und >> sind auf der Ebene der Python-Operatoren nicht angebunden. Die Funktionsformen left_shift() und right_shift() funktionieren:
np.left_shift(a, 2)
np.right_shift(b, 1)
6.8.3. Vergleich¶
==, !=, <, <=, >, >= liefern alle ein bool-ndarray der Broadcast-Form zurück:
a = np.array([1, 2, 3, 4, 5], dtype=np.uint8)
print(a < 3)
# array([True, True, False, False, False], dtype=bool)
Das boolesche Ergebnis ist genau das, was Indizierung und Auswahl und Umsortierung verarbeiten.
6.8.3.1. Die Seitenregel¶
Das ndarray muss beim Vergleich mit einem Skalar auf der linken Seite eines Relationsoperators stehen. a > 2 funktioniert; 2 < a löst einen TypeError aus. Verwenden Sie für die symmetrische Form die Funktionsnamen:
np.greater(5, a) # 5 > a, element-wise
np.less(5, a) # 5 < a, element-wise
np.equal(5, a) # 5 == a, element-wise
np.not_equal(5, a) # 5 != a, element-wise
6.8.4. Unäre Operatoren¶
+a– liefert eine Kopie des Arrays zurück.-a– Negation. Bei vorzeichenlosen dtypes laufen die Werte modulo \(2^N\) um, genauso wie es die binären Operatoren tun.abs(a)– elementweiser Absolutwert. Bei vorzeichenlosen dtypes wird ohne Berechnung eine Kopie zurückgegeben.~a– bitweise Invertierung (nur Ganzzahl-Arrays).len(a)– liefert die Länge der ersten Achse zurück, entsprechend der Python-Sequenzkonvention.
6.8.5. Was fehlt¶
Die rechtsseitigen Operatoren für den Vergleich und einige der bitweisen Operationen sind nicht auf dieselbe Weise implementiert wie die arithmetischen Operatoren. Verwenden Sie die Funktionsformen (oben), wenn ein ndarray auf der rechten Seite landen würde.
Die vollständige Liste der unterstützten Operatoren und der von ihnen befolgten Aufwärtskonvertierung finden Sie unter numpy — numpy-kompatible Array-Operationen.