Vectorisation et diffusion en Python

Publié: 2020-12-01

La vectorisation et la diffusion sont des moyens d'accélérer le temps de calcul et d'optimiser l'utilisation de la mémoire tout en effectuant des opérations mathématiques avec Numpy. Ces méthodes sont cruciales pour garantir que la complexité temporelle est réduite afin que les algorithmes ne soient pas confrontés à des goulots d'étranglement. Ce fonctionnement optimisé est nécessaire pour que les applications soient évolutives. Nous allons passer en revue ces deux techniques et implémenter quelques exemples.

À la fin de ce didacticiel, vous aurez les connaissances suivantes :

  • Comment la vectorisation est gérée par Numpy
  • Décalages horaires avec et sans vectorisation
  • Qu'est-ce que la radiodiffusion
  • En quoi la diffusion est différente de la multiplication matricielle habituelle

Vectorisation

Nous avons souvent besoin d'opérations mathématiques sur des tableaux, telles que la multiplication de tableaux. Maintenant, une manière non vectorisée serait de faire une multiplication élément par élément en utilisant une boucle. L'implémenter de cette manière entraînerait la même opération de multiplication à effectuer plusieurs fois, ce qui serait un gaspillage de ressources de calcul si la taille des données est trop importante. Jetons un coup d'œil rapide.

Manière non vectorisée :

Importation aléatoire

a = [random.randint( 1 , 100 ) for _ in range( 10000 )]
b = [random.randint( 1 , 100 ) for _ in range( 10000 )]
%timeit [i*j pour i, j dans zip(a,b)]

#Sortir:
>> 1000 boucles, meilleur des 3 : 658 µs par boucle

Façon vectorisée :

importer numpy en tant que np
a = np.array([random.randint( 1 , 100 ) for _ in range( 10000 )])
b = np.array([random.randint( 1 , 100 ) for _ in range( 10000 )])
%timeit a*b

#Sortir:
>> 100000 boucles, au mieux des 3 : 7,25 µs par boucle

Comme on le voit, le temps écoulé est passé de 658 microsecondes à seulement 7,25 microsecondes. En effet, lorsque nous disons a = np.array([]) , toutes les opérations sont gérées en interne par numpy. Et lorsque nous faisons a*b , numpy multiplie en interne le tableau complet à la fois au moyen de la vectorisation.

Ici, nous utilisons la commande magique %timeit pour chronométrer l'exécution du processus qui peut différer sur votre machine.

Examinons un autre exemple de produits extérieurs de 2 vecteurs de dimensions (nx1) et (1xm). La sortie sera (nxm).

temps d'importation
importer numpy
tableau d'importation
a = array.array( 'i' , [random.randint( 1 , 100 ) for _ in range( 100 )])
b = array.array( 'i' , [random.randint( 1 , 100 ) for _ in range( 100 )])

T1 = temps.process_time()
c = numpy. zéros(( 200 , 200 ))

pour je dans la plage (len (a)):
pour j dans la plage (len (b)):
c[i][j]= a[i]*b[j]

T2 = temps.process_time()

print( f”Temps de calcul = { 1000 *(T2-T1)} ms” )

#Sortir:
>> Temps de calcul = 6,819299000000001 ms

Maintenant, faisons-le avec Numpy,

T1 = temps.process_time()
c = numpy.outer(a, b)
T2 = temps.process_time()

print( f”Temps de calcul = { 1000 *(T2-T1)} ms” )

#Sortir:
>> Temps de calcul = 0,2256630000001536 ms

Comme nous le voyons encore, Numpy traite la même opération beaucoup plus rapidement par vectorisation.

Doit lire : Applications Python fascinantes dans le monde réel

Diffusion

Donc jusqu'à présent, nous avons vu des exemples où des tableaux de même taille étaient utilisés. Que se passe-t-il si les tailles des tableaux sont différentes ? C'est ici qu'une autre fonctionnalité intéressante de Numpy, la diffusion, entre en scène.

La diffusion est une autre extension de la vectorisation où les tableaux n'ont pas besoin d'être de la même taille pour que des opérations soient effectuées dessus comme l'addition, la soustraction, la multiplication, etc. Comprenons cela par un exemple très simple d'addition d'un tableau et d'un scalaire.

a = np.tableau([ 1 , 1 , 1 , 1 ])
un+ 5

#Sortir:
tableau([ 6 , 6 , 6 , 6 ])

Comme on le voit, le scalaire 5 a été ajouté à tous les éléments. Alors, comment est-ce arrivé?

Pour imaginer le processus, on peut penser que le scalaire 5 est répété 4 fois pour faire un tableau qui s'ajoute ensuite au tableau a. Mais gardez à l'esprit que Numpy ne crée pas de tels tableaux qui ne prendront que de la mémoire. Numpy "diffuse" ou duplique simplement le scalaire de 5 à 4 emplacements pour l'ajouter au tableau a.

Prenons un autre exemple simple.

a = np.ones(( 3 , 3 ))
b = np.ones( 3 )
a+b

#Sortir:
>> tableau([[ 2. , 2. , 2. ],
[ 2. , 2. , 2. ],
[ 2. , 2. , 2. ]])

Dans l'exemple ci-dessus, le tableau de forme (3,1) a été diffusé sur (3,3) pour correspondre au tableau a.

Mais cela signifie-t-il que n'importe quel tableau de n'importe quelle dimension peut être diffusé pour correspondre à un tableau de n'importe quelle dimension ?

NON!

Règles de diffusion

Numpy suit un ensemble de règles simples pour s'assurer que seuls les tableaux suivant les critères sont diffusés. Nous allons jeter un coup d'oeil.

La règle de diffusion dit que les 2 tableaux qui doivent être opérés doivent soit avoir les mêmes dimensions soit si l'un d'eux vaut 1.

Voyons ce qui est en action.

Exemple 1:

Considérez ci-dessous les tableaux de dimensions :

un = 3 x 4 x 7

b = 3 x 4 x 1

Ici, la dernière dimension de b sera diffusée pour correspondre à celle de a à 7.

Par conséquent, résultat = 3 x 4 x 7

Exemple 2 :

un = 3 x 4 x 7

b = 4

Or, le nombre de dimensions de a et b est inégal. Dans de tels cas, le tableau avec le moins grand nombre de dimensions sera rempli avec 1.

Donc, ici, les première et dernière dimensions de b sont 1, elles seront donc diffusées pour correspondre à celles de a à 3 et 7.

Par conséquent, résultat = 3 x 4 x 7.

Lire : Tutoriel Python

Exemple 3 :

un = 3 x 4 x 1 x 5

b = 3 × 1 × 7 × 1

Ici encore, la deuxième et la dernière dimension de b seront diffusées pour correspondre à celles de a à 4 et 5. De plus, la troisième dimension de a sera diffusée pour correspondre à celle de b à 7.

Par conséquent, résultat = 3 x 4 x 7 x 5

Voyons maintenant quand la condition échoue :

Exemple 4 :

un = 3 x 4 x 7 x 5

b = 3 × 3 × 7 × 4

Ici, les deuxième et quatrième dimensions de b ne correspondent pas à a et elles ne valent pas non plus 1. Dans ce cas, Python renverra une erreur de valeur :

ValueError : les opérandes n'ont pas pu être diffusés avec les formes ( 3 , 4 , 7 , 5 ) ( 3 , 3 , 7 , 4 )

Exemple 5 :

un = 3 x 4 x 1 x 5

b = 3 x 2 x 3

Résultat : ValueError

Ici aussi, la deuxième dimension ne correspond pas et n'est ni 1 ni pour l'une ni pour l'autre.

Avant que tu partes

La vectorisation et la diffusion, toutes deux, sont des méthodes par lesquelles Numpy rend son traitement optimisé et plus efficace. Ces concepts doivent être gardés à l'esprit, en particulier lorsqu'il s'agit de matrices et de tableaux à n dimensions, qui sont très courants dans les données d'image et les réseaux de neurones.

Si vous êtes curieux d'en savoir plus sur python, la science des données, consultez le diplôme PG de IIIT-B & upGrad en science des données qui est créé pour les professionnels en activité et propose plus de 10 études de cas et projets, des ateliers pratiques, un mentorat avec des experts de l'industrie, 1-on-1 avec des mentors de l'industrie, plus de 400 heures d'apprentissage et d'aide à l'emploi avec les meilleures entreprises.

Qu'est-ce que la vectorisation en Python ?

Numpy est un package Python fournissant plusieurs fonctions mathématiques standard permettant des opérations rapides sur de grands tableaux de données sans avoir besoin de boucles, y compris la vectorisation. La vectorisation est utilisée pour accélérer les programmes Python sans utiliser de boucles. L'utilisation d'une telle méthode peut aider à réduire le temps d'exécution du code. Diverses opérations sont effectuées sur des vecteurs, telles que le produit scalaire de vecteurs, également connu sous le nom de produit scalaire car il produit une sortie unique, des produits externes, qui se traduit par une matrice carrée de dimension égale à la longueur x longueur du vecteurs, multiplication élément par élément, qui produit des éléments avec les mêmes indices.

Qu'est-ce que la diffusion en Python ?

Le mot diffusion fait référence à la façon dont Numpy gère les tableaux avec des dimensions différentes lors d'opérations arithmétiques qui entraînent des restrictions spécifiques. le plus petit tableau est diffusé sur l'énorme tableau afin que leurs formes soient cohérentes. La diffusion vous permet de vectoriser les opérations de tableau de sorte que la boucle ait lieu en C plutôt qu'en Python, comme le fait Numpy. Il accomplit cela sans créer de copies inutiles de données, ce qui se traduit par des implémentations d'algorithmes efficaces. Dans certaines situations, la diffusion est une idée négative car elle entraîne une consommation inutile de mémoire, ce qui ralentit le traitement.

Quelles sont les utilisations de NumPy en Python ?

NumPy ou Numerical Python est une bibliothèque Python gratuite et open source utilisée par presque toutes les branches de recherche et d'ingénierie. La bibliothèque NumPy comprend des structures de données matricielles et matricielles multidimensionnelles et propose des méthodes pour opérer efficacement sur un tableau, un objet tableau homogène à n dimensions. Les utilisateurs peuvent utiliser NumPy pour exécuter un large éventail d'opérations mathématiques sur des tableaux. Il améliore Python avec des structures de données solides qui fournissent des calculs efficaces avec des tableaux et des matrices, ainsi qu'une bibliothèque massive de fonctions mathématiques de haut niveau qui fonctionnent sur ces tableaux et matrices.