NumPy en Python. 3e partie

Préface du traducteur


Bonjour encore! Poursuivant notre série d'articles sur la traduction du mana à propos de numpy. Bonne lecture.


Opérateurs de comparaison et tests de valeur


La comparaison booléenne peut être utilisée pour comparer par éléments des tableaux de même longueur. La valeur de retour est un tableau de valeurs booléennes Vrai / Faux:

>>> a = np.array([1, 3, 0], float) >>> b = np.array([0, 3, 2], float) >>> a > b array([ True, False, False], dtype=bool) >>> a == b array([False, True, False], dtype=bool) >>> a <= b array([False, True, True], dtype=bool) 

Le résultat de la comparaison peut être stocké dans un tableau:

 >>> c = a > b >>> c array([ True, False, False], dtype=bool) 

Les tableaux peuvent être comparés avec une seule valeur:

 >>> a = np.array([1, 3, 0], float) >>> a > 2 array([False, True, False], dtype=bool) 

Les opérateurs any et all peuvent être utilisés pour déterminer si au moins un ou tous les éléments sont vrais, respectivement:

 >>> c = np.array([ True, False, False], bool) >>> any(c) True >>> all(c) False 

Les expressions booléennes combinées peuvent être appliquées aux tableaux élément par élément à l'aide des fonctions spéciales logic_and, logic_or et logic_not:

 >>> a = np.array([1, 3, 0], float) >>> np.logical_and(a > 0, a < 3) array([ True, False, False], dtype=bool) >>> b = np.array([True, False, True], bool) >>> np.logical_not(b) array([False, True, False], dtype=bool) >>> c = np.array([False, True, False], bool) >>> np.logical_or(b, c) array([ True, True, False], dtype=bool) 

La fonction where crée un nouveau tableau à partir de deux autres tableaux de même longueur à l'aide d'un filtre booléen pour sélectionner entre deux éléments. Syntaxe de base: où (boolarray,
truearray, falsearray):

 >>> a = np.array([1, 3, 0], float) >>> np.where(a != 0, 1 / a, a) array([ 1. , 0.33333333, 0. ]) 

Avec la fonction where, la comparaison de masse peut également être implémentée:

 >>> np.where(a > 0, 3, 2) array([3, 3, 2]) 

Certaines fonctions permettent de tester des valeurs dans un tableau. La fonction non nulle renvoie un tuple d'indices de valeurs non nulles. Le nombre d'éléments dans le tuple est égal au nombre d'axes dans le tableau:

 >>> a = np.array([[0, 1], [3, 0]], float) >>> a.nonzero() (array([0, 1]), array([1, 0])) 

Vous pouvez également vérifier les valeurs de finitude et de NaN (pas un nombre):

 >>> a = np.array([1, np.NaN, np.Inf], float) >>> a array([ 1., NaN, Inf]) >>> np.isnan(a) array([False, True, False], dtype=bool) >>> np.isfinite(a) array([ True, False, False], dtype=bool) 

Bien que nous ayons utilisé des constantes numpy ici pour ajouter NaN et l'infini, elles peuvent être le résultat de l'application d'opérations mathématiques standard.

Sélection et manipulation des éléments du tableau


Nous avons déjà vu, comme pour les listes, que les éléments du tableau peuvent être obtenus en utilisant l'opération d'accès par index. Cependant, contrairement aux listes, les tableaux vous permettent également de sélectionner des éléments à l'aide d'autres tableaux. Cela signifie que nous pouvons utiliser un tableau pour filtrer des sous-ensembles spécifiques des éléments d'autres tableaux.

Les tableaux booléens peuvent être utilisés comme tableaux pour le filtrage:

 >>> a = np.array([[6, 4], [5, 9]], float) >>> a >= 6 array([[ True, False], [False, True]], dtype=bool) >>> a[a >= 6] array([ 6., 9.]) 

Il est à noter que lorsque nous passons un tableau booléen a> = 6 comme index pour l'opération d'accès par l'index du tableau a, le tableau retourné ne stockera que les valeurs True. Nous pouvons également écrire un tableau à filtrer dans une variable:

 >>> a = np.array([[6, 4], [5, 9]], float) >>> sel = (a >= 6) >>> a[sel] array([ 6., 9.]) 

Un filtrage plus sophistiqué peut être réalisé en utilisant des expressions booléennes:

 >>> a[np.logical_and(a > 5, a < 9)] >>> array([ 6.]) 

En plus de la sélection booléenne, vous pouvez également utiliser des tableaux entiers. Dans ce cas, le tableau d'entiers stocke les indices des éléments à extraire du tableau. Prenons l'exemple unidimensionnel suivant:

 >>> a = np.array([2, 4, 6, 8], float) >>> b = np.array([0, 0, 1, 3, 2, 1], int) >>> a[b] array([ 2., 2., 4., 8., 6., 4.]) 

En d'autres termes, lorsque nous utilisons b pour obtenir des éléments de a, nous prenons les 0e, 0e, 1er, 3e, 2e et 1er éléments de a dans cet ordre. Les listes peuvent également être utilisées comme tableaux pour le filtrage:

 >>> a = np.array([2, 4, 6, 8], float) >>> a[[0, 0, 1, 3, 2, 1]] array([ 2., 2., 4., 8., 6., 4.]) 

Pour les tableaux multidimensionnels, nous devons transférer plusieurs tableaux entiers unidimensionnels vers l'index de l'opérateur d'accès ( Traducteur de notes: dans notre cas, les index sont des tableaux ) pour chaque axe. Ensuite, chacun des tableaux passe par la séquence suivante: le premier élément correspond à l'index de la ligne, qui est le premier élément du tableau b, le deuxième élément correspond à l'index de la colonne, qui est le premier élément du tableau c, et ainsi de suite. ( Note du traducteur: le premier tableau [2, 2] et le second [1, 4], nous avons des éléments avec les indices [2, 1] et [2, 4] en sortie ) Exemple:

 >>> a = np.array([[1, 4], [9, 16]], float) >>> b = np.array([0, 0, 1, 1, 0], int) >>> c = np.array([0, 1, 1, 1, 1], int) >>> a[b,c] array([ 1., 4., 16., 16., 4.]) 

Une fonction de prise spéciale est disponible pour la récupération avec des tableaux entiers. Cela fonctionne de la même manière que l'utilisation de l'opérateur de prise sur un index:

 >>> a = np.array([2, 4, 6, 8], float) >>> b = np.array([0, 0, 1, 3, 2, 1], int) >>> a.take(b) array([ 2., 2., 4., 8., 6., 4.]) 

La fonction de prise fournit également l'argument axe pour prendre une sous-section du tableau multidimensionnel le long d'un axe. ( Remarque traducteur: ligne ou colonne (pour les tableaux à deux dimensions) ).

 >>> a = np.array([[0, 1], [2, 3]], float) >>> b = np.array([0, 0, 1], int) >>> a.take(b, axis=0) array([[ 0., 1.], [ 0., 1.], [ 2., 3.]]) >>> a.take(b, axis=1) array([[ 0., 0., 1.], [ 2., 2., 3.]]) 

Contrairement à la fonction take, il existe une fonction put, qui prend les valeurs du tableau d'origine et les écrit dans des indices spécifiques dans un autre put-array.

 >>> a = np.array([0, 1, 2, 3, 4, 5], float) >>> b = np.array([9, 8, 7], float) >>> a.put([0, 3], b) >>> a array([ 9., 1., 2., 8., 4., 5.]) 

Notez que la valeur 7 du tableau d'origine b n'a pas été utilisée, car seuls 2 index [0, 3] sont indiqués. Le tableau d'origine sera répété si nécessaire si les longueurs ne correspondent pas:

 >>> a = np.array([0, 1, 2, 3, 4, 5], float) >>> a.put([0, 3], 5) >>> a array([ 5., 1., 2., 5., 4., 5.]) 

Mathématiques vectorielles et matricielles


NumPy fournit de nombreuses fonctions pour travailler avec des vecteurs et des matrices. La fonction dot renvoie le produit scalaire des vecteurs:

 >>> a = np.array([1, 2, 3], float) >>> b = np.array([0, 1, 1], float) >>> np.dot(a, b) 5.0 

La fonction point peut également multiplier les matrices:

 >>> a = np.array([[0, 1], [2, 3]], float) >>> b = np.array([2, 3], float) >>> c = np.array([[1, 1], [4, 0]], float) >>> a array([[ 0., 1.], [ 2., 3.]]) >>> np.dot(b, a) array([ 6., 11.]) >>> np.dot(a, b) array([ 3., 13.]) >>> np.dot(a, c) array([[ 4., 0.], [ 14., 2.]]) >>> np.dot(c, a) array([[ 2., 4.], [ 0., 4.]]) 

Vous pouvez également obtenir le produit scalaire, tensoriel et externe des matrices et des vecteurs. Notez que pour les vecteurs, le produit interne et scalaire coïncident.

 >>> a = np.array([1, 4, 0], float) >>> b = np.array([2, 2, 1], float) >>> np.outer(a, b) array([[ 2., 2., 1.], [ 8., 8., 4.], [ 0., 0., 0.]]) >>> np.inner(a, b) 10.0 >>> np.cross(a, b) array([ 4., -1., -6.]) 

NumPy fournit également un ensemble de fonctions et de méthodes intégrées pour travailler avec l'algèbre linéaire. Tout cela se trouve dans le sous-module linalg. Ces modules peuvent également être exploités avec des matrices dégénérées et non dégénérées. Le déterminant de la matrice est recherché de cette façon:

 >>> a = np.array([[4, 2, 0], [9, 3, 7], [1, 2, 1]], float) >>> a array([[ 4., 2., 0.], [ 9., 3., 7.], [ 1., 2., 1.]]) >>> np.linalg.det(a) -48. 

Vous pouvez également trouver le vecteur propre et la valeur propre de la matrice:

 >>> vals, vecs = np.linalg.eig(a) >>> vals array([ 9. , 2.44948974, -2.44948974]) >>> vecs array([[-0.3538921 , -0.56786837, 0.27843404], [-0.88473024, 0.44024287, -0.89787873], [-0.30333608, 0.69549388, 0.34101066]]) 

Une matrice non dégénérée peut être trouvée comme suit:

 >>> b = np.linalg.inv(a) >>> b array([[ 0.14814815, 0.07407407, -0.25925926], [ 0.2037037 , -0.14814815, 0.51851852], [-0.27777778, 0.11111111, 0.11111111]]) >>> np.dot(a, b) array([[ 1.00000000e+00, 5.55111512e-17, 2.22044605e-16], [ 0.00000000e+00, 1.00000000e+00, 5.55111512e-16], [ 1.11022302e-16, 0.00000000e+00, 1.00000000e+00]]) 

Une décomposition unique (un analogue de la diagonalisation d'une matrice non carrée) peut être obtenue comme suit:

 >>> a = np.array([[1, 3,4], [5, 2, 3]], float) >>> U, s, Vh = np.linalg.svd(a) >>> U array([[-0.6113829 , -0.79133492], [-0.79133492, 0.6113829 ]]) >>> s array([ 7.46791327, 2.86884495]) >>> Vh array([[-0.61169129, -0.45753324, -0.64536587], [ 0.78971838, -0.40129005, -0.46401635], [-0.046676 , -0.79349205, 0.60678804]]) 

Nous terminons la troisième partie. Bonne chance et à bientôt!

Source: https://habr.com/ru/post/fr413381/


All Articles