Python >> Tutoriel Python >  >> Python Tag >> NumPy

Diffusion NumPy - Un tutoriel simple

La diffusion décrit comment NumPy amène automatiquement deux tableaux de formes différentes à une forme compatible lors d'opérations arithmétiques. Généralement, le plus petit tableau est "répété" plusieurs fois jusqu'à ce que les deux tableaux aient la même forme. La diffusion est économe en mémoire car elle ne copie pas le plus petit tableau plusieurs fois.

Voici un exemple minimal :

import numpy as np

A = np.array([1, 2, 3])
res = A * 3 # scalar is broadcasted to [3 3 3]
print(res)
# [3 6 9]

Passons ensuite à une introduction plus douce à la motivation et au concept.

Une représentation visuelle

La représentation visuelle suivante de deux opérations de diffusion montre

  • comment une valeur scalaire (0 dimensionnelle) peut être diffusée dans un tableau unidimensionnel, et
  • comment un tableau à 1 dimension peut être diffusé vers un tableau à 2 dimensions.

Dans les deux cas, vous copiez essentiellement le plus petit tableau jusqu'à ce que vous atteigniez la même forme que le plus grand tableau.

Présentation douce

De nombreuses opérations NumPy telles que la multiplication sont effectuées "élément par élément". Par exemple :disons que vous multipliez deux tableaux NumPy A et B avec la même forme :A * B .

Dans ce cas, NumPy effectue une multiplication matricielle élément par élément en multipliant la cellule A[i,j] avec la cellule B[i,j] pour chaque cellule des tableaux. Comme les tableaux ont la même forme, ce n'est pas un problème.

import numpy as np

salary = np.array([2000, 4000, 8000])
salary_bump = np.array([1.1, 1.1, 1.1])

print(salary * salary_bump)

Énigme : Quel est le résultat de cet extrait de code ?

Le puzzle montre un scénario dans lequel l'entreprise décide que tous les employés obtiennent une augmentation de salaire de 10 % après une année réussie.

Ainsi, le résultat du puzzle est le tableau NumPy :

# [2200. 4400. 8800.]

Jusqu'ici tout va bien. Mais que se passe-t-il si vous multipliez deux tableaux de formes différentes ?

La réponse est à nouveau :diffusion . Voici le même exemple mais nous sommes un peu paresseux maintenant et essayons d'économiser quelques bits.

salary = np.array([2000, 4000, 8000])
salary_bump = 1.1

print(salary * salary_bump)

Énigme : Quel est le résultat de cet extrait de code ?

Comme les trois valeurs du salary_bump sont exactement les mêmes nombres, vous essayez de le raccourcir en multipliant un tableau NumPy par un nombre. Ainsi, il produit exactement la même sortie.

# [2200. 4400. 8800.]

En interne, NumPy crée un deuxième tableau implicite qui est rempli avec la valeur de salaire 1.1. Ce tableau se présente comme suit :np.array([1.1, 1.1, 1.1]) . Cette procédure est appelée "diffusion".

Non seulement le code utilisant la diffusion est plus concis et lisible, mais il est aussi plus efficace ! Dans le premier exemple, le salary_bump tableau contient des redondances. Mais dans le deuxième exemple, NumPy se débarrasse de ces redondances - il ne copie pas vraiment les données dans un deuxième tableau NumPy, ce n'est que l'idée conceptuelle mais pas l'implémentation.

Comment appliquer la diffusion à deux tableaux NumPy ?

La diffusion n'est possible que si, along une seule dimension, un tableau a une taille de n mais l'autre une taille de 1. Sinon, vous ne pouvez pas effectuer d'opérations NumPy sur deux tableaux avec différent formes.

Les dimensions manquantes ne sont pas un problème dans ce scénario. Voici une belle visualisation de la documentation sur la façon dont les tableaux NumPy seront diffusés ensemble :

 A      (2d array):  5 x 4
 B      (1d array):      1
 Result (2d array):  5 x 4

 A      (2d array):  5 x 4
 B      (1d array):      4
 Result (2d array):  5 x 4

 A      (3d array):  15 x 3 x 5
 B      (3d array):  15 x 1 x 5
 Result (3d array):  15 x 3 x 5

 A      (3d array):  15 x 3 x 5
 B      (2d array):       3 x 5
 Result (3d array):  15 x 3 x 5

 A      (3d array):  15 x 3 x 5
 B      (2d array):       3 x 1
 Result (3d array):  15 x 3 x 5

Une observation importante est la suivante :Pour toute dimension où le premier tableau a une taille de un, NumPy copie conceptuellement ses données jusqu'à ce que la taille du second tableau soit atteinte. De plus, si la dimension est complètement manquante pour le tableau B, elle est simplement copiée également le long de la dimension manquante.

Exercice  :essayez de comprendre ce qui se passe ici dans le premier exemple de la visualisation donnée.

En résumé, la diffusion correspond automatiquement à deux tableaux de forme incompatible - une belle fonctionnalité de la bibliothèque NumPy !

Diffusion vidéo associée

Dans la vidéo suivante de mon livre Python One-Liners, je parle également de la diffusion. Consultez-le pour mieux comprendre ce concept crucial de Python :