English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
NumPy fournit deux types d'objets de base, à savoir ndarray et objets ufunc. Ufunc est l'abréviation de universal function, ce qui signifie “fonction universelle”, c'est une fonction qui peut opérer sur chaque élément d'un tableau.
De nombreuses fonctions ufunc sont implémentées au niveau du langage C, donc elles sont très rapides en termes de calcul.
En plus, ufun est plus flexible que les fonctions du module math. Les entrées du module math sont généralement des scalaires, mais les fonctions de NumPy peuvent être des vecteurs ou des matrices, et utiliser des vecteurs ou des matrices peut éviter l'utilisation de boucles, ce qui est très important dans l'apprentissage automatique et l'apprentissage profond.
Ufunc est utilisé pour la vectorisation dans NumPy, ce qui est beaucoup plus rapide que l'itération des éléments.
Ils fournissent également des méthodes de diffusion et d'autres, telles que la réduction, l'ajout, etc., ce qui est très utile pour les calculs.
Les ufunc acceptent également d'autres paramètres, par exemple :
where est un tableau de valeurs booléennes ou une condition, utilisé pour définir où l'opération doit être effectuée.
dtype définit le type de retour des éléments.
La valeur de retour out doit être copiée dans le tableau de sortie.
Fonction | Méthode d'utilisation |
sqrt() | Calcul de la racine carrée des données sérialisées |
sin()、cos() | Fonctions trigonométriques |
abs() | Calcul de l'absolu des données sérialisées |
dot() | Opérations matricielles |
log()、logl()、log2() | Fonction logarithmique |
exp() | Fonction exponentielle |
cumsum()、cumproduct() | Somme et produit cumulés |
sum() | Somme d'une séquence sérialisée |
mean() | Calcul de la moyenne |
median() | Calcul de la médiane |
std() | Calcul de l'écart type |
var() | Calcul de la variance |
corrcoef() | Calcul de la corrélation |
import time import math import numpy as np x = [i * 0.001 for i in np.arange(1000000) start = time.clock() for i, t in enumerate(x): x[i] = math.sin(t) print("math.sin:", time.clock()) - start) x = [i * 0.001 for i in np.arange(1000000) x = np.array(x) start = time.clock() np.sin(x) print("numpy.sin:", time.clock()) - start)
Résultat de l'exécution :
math.sin: 0.5169950000000005 numpy.sin: 0.05381199999999886
Il ressort donc que numpy.sin est presque aussi rapide que math.sin. 10 fois.
Convertir une instruction itérative en une opération vectorielle s'appelle vectorisation.
Comme les CPU modernes sont optimisés pour ce type d'opération, la vitesse est plus rapide.
Additionner les éléments des deux listes :
list 1: [1, 2, 3, 4]
list 2: [4, 5, 6, 7]
Une méthode consiste à parcourir les deux listes et à additionner chaque élément.
Si l'ufunc n'est pas disponible, nous pouvons utiliser la méthode intégrée zip() de Python :
x = [1, 2, 3, 4] y = [4, 5, 6, 7] z = [] for i, j in zip(x, y): z.append(i + j) print(z)
Résultat de l'exécution :
[5, 7, 9, 11]
Pour cela, NumPy dispose d'une ufunc appelée add(x, y), qui génère le même résultat. Grâce à l'ufunc, nous pouvons utiliser la fonction add() :
import numpy as np x = [1, 2, 3, 4] y = [4, 5, 6, 7] z = np.add(x, y) print(z)
Résultat de l'exécution :
[5, 7, 9, 11]
Utiliser pleinement les fonctions intégrées de la bibliothèque NumPy de Python (Built-en utilisant la vectorisation dans la fonction (Function), cela peut grandement améliorer la vitesse d'exécution. Les fonctions intégrées de la bibliothèque NumPy utilisent des instructions SIMD. Comme l'utilisation de la vectorisation est beaucoup plus rapide que le calcul avec une boucle, si l'on utilise un GPU, la performance sera encore plus puissante, bien que NumPy ne supporte pas le GPU.
Voyons le code suivant :
import time import numpy as np x1 = np.random.rand(1000000) x2 = np.random.rand(1000000) ##Calcul du produit scalaire en utilisant une boucle tic = time.process_time() dot = 0 for i in range(len(x1)) : dot+= x1[i]*x2[i] toc = time.process_time() print("dot = " + str(dot) + ##Boucle for-----Temps de calcul = " + str(1000*(toc - tic)) + "ms") ##Calcul du produit scalaire en utilisant la fonction numpy tic = time.process_time() dot = 0 dot = np.dot(x1,x2) toc = time.process_time() print("dot = " + str(dot) + "\nVersion Vector---- Temps de calcul = " + str(1000*(toc - tic)) + "ms")
Résultat de l'exécution :
dot = 250215.601995 Boucle for-----Temps de calcul = 798.3389819999998ms dot = 250215.601995 Version Vector---- Temps de calcul = 1.885051999999554ms