6.8. Opérateurs

Le premier type de calcul que numpy exécute sur un ndarray est celui des opérateurs Python standard. Les opérateurs arithmétiques, de comparaison et bit à bit fonctionnent tous élément par élément – chaque opérateur parcourt le tableau (ou les deux tableaux) une fois du début à la fin au sein d’un unique appel de bibliothèque, bien plus rapidement que la boucle Python for équivalente.

6.8.1. Arithmétique

+, -, *, /, //, %, ** fonctionnent tous entre deux tableaux de forme compatible, ou entre un tableau et un scalaire

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

Le dtype du résultat suit les règles de promotion décrites dans Dtypes. Les tableaux d’entiers bouclent en cas de dépassement ; convertissez vers un dtype plus large avant l’opération lorsque cela importe.

L’opérateur de multiplication matricielle @ n’est pas implémenté. Utilisez dot() pour les produits matrice / vecteur.

6.8.1.1. Formes sur place

Chaque opérateur arithmétique a une forme sur place – +=, -=, *=, /=, %=, **=. La forme sur place écrit dans le tampon existant au lieu d’allouer un temporaire

b = b + 1            # allocates a temporary the size of b
b += 1               # no temporary

Sur un microcontrôleur, la seconde forme est essentiellement obligatoire pour toute boucle critique.

6.8.2. Bit à bit

Les opérateurs bit à bit &, |, ^ fonctionnent élément par élément sur les tableaux d’entiers. Appliqués à un tableau float ou complex, ils lèvent TypeError

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)

L’opérateur unaire ~ effectue un NON bit à bit sur un tableau d’entiers.

Les opérateurs de décalage << et >> ne sont pas câblés au niveau des opérateurs Python. Les formes fonctionnelles left_shift() et right_shift() fonctionnent

np.left_shift(a, 2)
np.right_shift(b, 1)

6.8.3. Comparaison

==, !=, <, <=, >, >= retournent tous un ndarray de bool de la forme issue de la diffusion

a = np.array([1, 2, 3, 4, 5], dtype=np.uint8)
print(a < 3)
# array([True, True, False, False, False], dtype=bool)

Le résultat booléen est exactement ce que consomment l”indexation et la Sélection et réorganisation.

6.8.3.1. La règle du côté

Le ndarray doit se trouver à gauche d’un opérateur relationnel lors d’une comparaison à un scalaire. a > 2 fonctionne ; 2 < a lève TypeError. Pour la forme symétrique, utilisez les noms de fonctions

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. Opérateurs unaires

  • +a – retourne une copie du tableau.

  • -a – négation. Sur les dtypes non signés, les valeurs bouclent modulo \(2^N\), de la même manière que les opérateurs binaires.

  • abs(a) – valeur absolue élément par élément. Sur les dtypes non signés, retourne une copie sans calcul.

  • ~a – inversion bit à bit (tableaux d’entiers uniquement).

  • len(a) – retourne la longueur du premier axe, conformément à la convention des séquences Python.

6.8.5. Ce qui manque

Les opérateurs côté droit pour la comparaison et certaines des opérations bit à bit ne sont pas implémentés de la même manière que les opérateurs arithmétiques. Utilisez les formes fonctionnelles (ci-dessus) lorsqu’un ndarray se retrouverait à droite.

Pour la liste complète des opérateurs pris en charge et la promotion de type qu’ils suivent, consultez numpy — opérations sur tableaux compatibles numpy.