Maison > Article > développement back-end > au revoir! Boucle Python, la vectorisation est incroyable
Nous avons appris les boucles dans presque tous les langages de programmation. Ainsi, par défaut, chaque fois qu’il y a une opération répétitive, nous commençons à implémenter des boucles. Mais lorsque nous avons affaire à de nombreuses itérations (millions/milliards de lignes), utiliser des boucles est vraiment pénible, et vous pourriez rester bloqué pendant des heures, pour vous rendre compte plus tard que cela ne fonctionne pas. C'est là que l'implémentation de la vectorisation en Python devient extrêmement critique.
La vectorisation est une technique d'implémentation d'opérations de tableau (NumPy) sur des ensembles de données. En coulisses, il opère sur tous les éléments du tableau ou de la série à la fois (contrairement à une boucle « for », qui opère une ligne à la fois).
Dans ce blog, nous examinerons quelques cas d'utilisation où nous pouvons facilement remplacer les boucles Python par la vectorisation. Cela vous aidera à gagner du temps et à devenir plus compétent en codage.
Tout d'abord, examinons un exemple de base de recherche de la somme de nombres en Python à l'aide de boucles et de vecteurs.
import time start = time.time() # 遍历之和 total = 0 # 遍历150万个数字 for item in range(0, 1500000): total = total + item print('sum is:' + str(total)) end = time.time() print(end - start) #1124999250000 #0.14 Seconds
import numpy as np start = time.time() # 向量化和--使用numpy进行向量化 # np.range创建从0到1499999的数字序列 print(np.sum(np.arange(1500000))) end = time.time() print(end - start) ##1124999250000 ##0.008 Seconds
Le temps d'exécution de la vectorisation est d'environ 18 fois par rapport à l'itération utilisant les fonctions de plage. Cette différence devient encore plus évidente lorsque l'on travaille avec Pandas DataFrame.
En science des données, lorsqu'ils travaillent avec Pandas DataFrame, les développeurs utilisent des boucles pour créer de nouvelles colonnes dérivées pour les opérations mathématiques.
Dans l'exemple ci-dessous, nous pouvons voir que les boucles peuvent facilement être remplacées par la vectorisation dans de tels cas d'utilisation.
DataFrame est des données tabulaires sous forme de lignes et de colonnes.
Nous créons un DataFrame pandas avec 5 millions de lignes et 4 colonnes remplies de valeurs aléatoires entre 0 et 50.
import numpy as np import pandas as pd df = pd.DataFrame(np.random.randint(0, 50, size=(5000000, 4)), columns=('a','b','c','d')) df.shape # (5000000, 5) df.head()
Nous allons créer une nouvelle colonne 'rapport' pour trouver le rapport des colonnes 'd' et 'c'.
import time start = time.time() # Iterating through DataFrame using iterrows for idx, row in df.iterrows(): # creating a new column df.at[idx,'ratio'] = 100 * (row["d"] / row["c"]) end = time.time() print(end - start) ### 109 Seconds
start = time.time() df["ratio"] = 100 * (df["d"] / df["c"]) end = time.time() print(end - start) ### 0.12 seconds
On constate une nette amélioration dans le DataFrame, la vectorisation est presque 1000 fois plus rapide par rapport aux boucles en python.
Nous avons implémenté de nombreuses opérations qui nous obligent à utiliser une logique de type "if-else". On peut facilement remplacer cette logique par des opérations vectorisées en python.
Jetez un œil à l'exemple ci-dessous pour mieux le comprendre (nous utiliserons le DataFrame créé dans le cas d'utilisation 2).
Imaginez comment créer une nouvelle colonne « e » en fonction de certaines conditions de la colonne « a » quittée.
import time start = time.time() # Iterating through DataFrame using iterrows for idx, row in df.iterrows(): if row.a == 0: df.at[idx,'e'] = row.d elif (row.a <= 25) & (row.a > 0): df.at[idx,'e'] = (row.b)-(row.c) else: df.at[idx,'e'] = row.b + row.c end = time.time() print(end - start) ### Time taken: 177 seconds
start = time.time() df['e'] = df['b'] + df['c'] df.loc[df['a'] <= 25, 'e'] = df['b'] -df['c'] df.loc[df['a']==0, 'e'] = df['d']end = time.time() print(end - start) ## 0.28007707595825195 sec
Par rapport aux boucles python avec des instructions if-else, les opérations vectorisées sont 600 fois plus rapides que les boucles.
L'apprentissage profond nous oblige à résoudre plusieurs équations complexes, et cela concerne des millions et des milliards de lignes d'équations. Exécuter des boucles en Python pour résoudre ces équations est très lent, auquel cas la vectorisation est la meilleure solution.
Par exemple, vous souhaitez calculer les valeurs y pour des millions de lignes dans l'équation de régression multilinéaire suivante.
Nous pouvons utiliser la vectorisation au lieu du bouclage. Les valeurs de
m1,m2,m3... sont déterminées en résolvant l'équation ci-dessus en utilisant des millions de valeurs correspondant à x1,x2,x3... (pour plus de simplicité, il suffit de regarder une simple étape de multiplication)
>>> import numpy as np >>> # 设置 m 的初始值 >>> m = np.random.rand(1,5) array([[0.49976103, 0.33991827, 0.60596021, 0.78518515, 0.5540753]]) >>> # 500万行的输入值 >>> x = np.random.rand(5000000,5)
import numpy as np m = np.random.rand(1,5) x = np.random.rand(5000000,5) total = 0 tic = time.process_time() for i in range(0,5000000): total = 0 for j in range(0,5): total = total + x[i][j]*m[0][j] zer[i] = total toc = time.process_time() print ("Computation time = " + str((toc - tic)) + "seconds") ####Computation time = 28.228 seconds
tic = time.process_time() #dot product np.dot(x,m.T) toc = time.process_time() print ("Computation time = " + str((toc - tic)) + "seconds") ####Computation time = 0.107 seconds
np.dot implémente la multiplication matricielle de vecteurs dans le backend. C'est 165 fois plus rapide que les boucles en python.
La vectorisation en Python est très rapide, et lorsque vous traitez de très grands ensembles de données, il est recommandé de donner la priorité à la vectorisation plutôt qu'aux boucles. De cette façon, au fil du temps, vous vous habituerez progressivement à écrire du code selon des idées de vectorisation.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!