Package numpy

 

numpy est une bibliothèque de méthodes gérant des tableaux multi-dimensionnels pour des applications scientifiques: calcul matriciel, calcul statistique…
L’affichage des tableaux créés avec numpy est conforme à la représentation habituelle, à savoir avec des lignes et des colonnes, ce qui est plus convivial, surtout quand on effectue des opérations sur ces tableaux, tels que produits scalaire et matriciel.
Si vous n’avez pas encore téléchargé la suite Anaconda (2 ou 3) c’est le moment: les packages numpy, scipy, pandas et bien d’autres sont inclus.
Sinon, les dernières distributions de Python incluent ce package.
L’installation est immédiate: sur Windows, taper cmd (bouton office > zone d’édition tout en bas). Si le dossier à partir duquel vous voulez installer numpy n’apparaît pas, taper cd/ pour revenir au menu racine, puis cd/votre_dossier. Ici, nous avons choisi le répertoire Python34.
Puis, taper

pip install numpy

C’est fait.
Dans les exemples applicatifs qui vont suivre, nous allons faire référence au package numpy en lui attribuant un alias np, c’est à dire placer en début de module

import numpy as np

Cet alias permet de raccourcir la référence à numpy (np.ndarray est plus court que numpy.ndarray). L’instruction

from numpy import *

est fortement déconseillée, sachant que les fonctions définies dans ce package portent des noms (add, sum, sqrt…) qu’elles partagent avec d’autres packages.
Dans cette page, seront abordées

  1. Création et dimensionnement des tableaux
  2. Opérations sur les tableaux
  3. Fonctions statistiques
  4. Fonctionnalités avancées: packages numpy.linalg , numpy.fft
  5. Quelques mots sur scipy

Cette page ne présente que les bases de numpy: pour une approche plus exhaustive, se reporter au tutoriel fourni par scipy

Création et dimensionnement des tableaux

 

Création d’un tableau

Pour initialiser un tableau, on utilise la méthode array, qui restitue un objet de type numpy.ndarray. Cette méthode prend en argument une séquence qu’elle remet en forme: liste ou tuplet, le résultat est identique.

La i-ème ligne d’un tableau a est a[i], la i-ème colonne est a[:,i]

Quand il est nécessaire d’expliciter le type des éléments présents dans le tableau (ndarray), on ajoute un argument en précisant le mot-clé dtype. C’est le cas, par exemple, lorsqu’on veut manipuler des tableaux de nombres complexes.

On peut aussi créer un tableau « en compréhension ». Par exemple,

On peut aussi utiliser le raccourci offert par la méthode arange qui joue le même rôle que range dans la création des séquences et des générateurs.

On notera l’absence de virgules dans l’affichage des tableaux, ce qui leur donne un authentique aspect de matrice.
Pour formater les éléments d’un tableau qui sont affichés par défaut avec la précision due aux valeurs de type float, on utilise la fonction round qui prend comme arguments le tableau et le nombre de chiffres après la virgule.


Dans le paragraphe qui suit, nous allons voir comment redimensionner un tableau de manière à faciliter la création des matrices

Dimensionnement des tableaux

La méthode arange ne permet de créer que des tableaux uni-dimensionnels, et la création de matrices en compréhension peut s’avérer laborieuse. C’est pourquoi numpy contient des méthodes qui, en redimensionnant les tableaux, permettent de passer facilement d’un vecteur à une matrice et vice-versa.

reshape

La méthode reshape prend en arguments deux nombres entiers, le nombre de lignes en premier, et de colonnes en second. L’exemple qui suit montre comment arriver simplement au calcul de la matrice c (voir paragraphe précédent)

On peut créer des tableaux à 3 dimensions. Au delà, l’affichage devient peu lisible.

L’affichage laisse un espace intermédiaire permettant de séparer le tableau en deux parties, chacune contenant une matrice 2×3, pour constituer finalement un tableau 2x2x3.

flatten, ravel

Ces deux méthodes permettent de réduire la dimension d’un tableau à 1, en alignant tous ses éléments dans une liste: en gros c’est le chemin inverse de reshape.
flatten crée une liste à partir d’une copie du tableau original tandis que ravel n’offre qu’une vue du tableau transformé. L’exemple suivant illustre cette différence

La méthode flatten prend des arguments optionnels pour préciser l’ordre dans lequel les éléments vont être alignés. Par défaut, l’alignement se fait ligne à ligne, mais pour un alignement colonne par colonne, on rajoute l’argument « F ».

zeros, ones, random, eye,linspace

Ces méthodes permettent de créer des matrices remplies de 0, de 1, ou de valeurs aléatoires uniformes dans [0,1] (ne pas oublier les doubles parenthèses à l’intérieur). La fonction eye crée une matrice identité

La fonction linspace crée des tableaux de valeurs équidistantes à l’intérieur d’un intervalle donné. Les deux premiers arguments sont les deux bornes de l’intervalle, le troisième étant le nombre de valeurs que cet intervalle peut contenir, sachant que les deux bornes de l’intervalle sont inclues dans le tableau.


&nbp;

attributs shape, ndim,size,size,class= »keyw »>dtype

Ces attributs renseignent sur le format d’un objet ndarray: par exemple,

Ces attributs sont (presque tous) modifiables

Opérations sur les tableaux

Addition, soustraction, multiplication de matrices

On utilise les mêmes opérateurs +, – et * que pour des valeurs numériques simples


L’opérateur * fait le produit terme à terme des éléments de deux matrices: celles-ci doivent avoir le même format

Pour un authentique produit matriciel, on utilise la méthode dot (AxB == A.dot(B))

Opérations composées

Il est possible de combiner un opérateur arithmétique et une assignation pour modifier un tableau


A la différence des variables simples, on ne peut appliquer ces opérateurs composés à deux tableaux (i.e. A+=B n’est pas autorisé)

 

Opérations unaires

Les calculs s’effectuent élément par élément

Empilement de matrices (vstack)

Pour empiler deux tableaux (généralement deux matrices) ou simplement ajouter une ligne à un tableau, on utilise la fonction vstack en plaçant les noms des deux tableaux entre crochets

Fonctions statistiques

 

Moyenne et écart-type

Ces fonctions s’appliquent aux données d’un tableau multi-dimensionnel. Par exemple, mean, moyennes arithmétique, average, moyenne pondérée, et std, écart-type, reçoivent en arguments

  • le tableau de données
  • dans le cas d’une matrice, l’axe selon lequel on effectue le calcul: 0 → les statistiques se calculent colonne par colonne, 1→ ligne par ligne
  • la séquence (liste ou tuplet) des coefficients de pondération [optionnel]: si leur somme est supérieure à 1, ces coefficients sont normalisés

 

 
Si l’axe n’est pas spécifié, la statistique est calculée sur l’ensemble des données
 

 

Corrélation

La fonction corrcoef calcule la matrice de corrélations linéaires entre plusieurs séries. Pour deux séries, le calcul est direct
 

 
Pour 3 séries et au-delà, la fonction corrcoef prend en argument une matrice et calcule les coefficients de corrélation des colonnes 2 à 2: il faut donc commencer par construire une telle matrice à partir des n séries. Pour cela, on crée un objet de type ndarray en mettant les séries bout à bout (on obtient un vecteur dont la longueur est égale à la longueur de chaque série multipliée par le nombre de séries). Puis, on redimensionne la série en divisant ce vecteur en autant de colonnes que de séries à l’aide de reshape
 

 

Fonctionnalités avancées: packages numpy.linalg , numpy.fft

L’utilisation des fonctions avancées fournies dans ces « sous-packages » de numpy renforce l’intérêt d’inclure des portions de programme python dans votre projet VBA.

numpy.linalg (https://docs.scipy.org/doc/numpy/reference/routines.linalg.html pour une présentation exhaustive)

linalg → linear algebra
Ce package contient des fonctions qui effectuent des traitements propres à l’algèbre linéaire, comme le calcul de déterminant, de valeurs propres, la trigonalisation (décomposition de Cholesky), l’inversion de matrices, etc.

matrix_rank
Comme il fallait s’y attendre, cette méthode renvoie le rang d’une matrice
 

 

det
Déterminant

solve, inv interviennent dans la résolution des systèmes linéaires.
Soit le système
Ax=B
Il se résout par
x=ng.solve(A,B)
ou
x=ng.inv(A).dot(B)
Ex: soit le système
2x+5y=3
x-2y=4

 

 
NB: on notera que, pour utiliser les méthodes et fonctions du package numpy, il n’est souvent pas nécessaire de convertir les séquences en objets ndarray

Fonctions de l’analyse numérique: eig (eigh, eigvals), cholesky

Ces fonctions sont issues des algorithmes de l’analyse numérique: elles servent beaucoup en Finance et, plus généralement, en Statistiques (en particulier pour l’Analyse en Composantes Principales)
Elles sont données à titre d’exemples car leur emploi est très fréquent: d’autres fonctions (décomposition singulière, factorisation QR, calcul de valeurs propres appliquées aux matrices hermitiennes,…) sont présentées sur le site officiel de Scipy.

eig
Renvoie un tuplet contenant deux objets ndarray: les valeurs propres (tableau uni-dimensionnel) et les vecteurs propres (matrice) d’une matrice carrée quelconque. Les vecteurs propres sont normalisés.
Quand la matrice est symétrique (corps des réels) ou hermitienne (corps des complexes), python utilise un algorithme particulier à l’intérieur de la fonction eigh:
NB:l’ordre dans lequel apparaissent les vecteurs propres diffère entre eigh et eigSoit m, une matrice carrée symétrique, la matrice des vecteurs propres est donnée par le deuxième élément du tuplet renvoyé par eigh, c’est à dire ng.eigh(m)[1]: sachant que ces vecteurs propres sont en colonnes, le 1er vecteur propre par exemple est donné par ng.eigh(m)[1][:,0]. Les valeurs propres sont données par ng.eigh(m)[0].
Dans l’exemple ci-dessous, une matrice symétrique 4×4 est générée aléatoirement. On vérifie que M.x=λ.x sur les deux premier(e)s vecteurs (valeurs) propres.
 

 
eigvals retourne uniquement les valeurs propres d’une matrice non symétrique
 
cholesky

La décomposition de Cholesky permet, à partir d’une matrice M symétrique définie positive, de calculer la matrice T triangulaire inférieure (des 0 au-dessus de la diagonale) telle que

T*tT = M (T.dot(transpose(T)) = M)

La matrice triangulaire obtenue permet de produire des échantillons de nombres aléatoires reliés par une loi normale multi-variée. Elle permet, en générant aléatoirement des paramètres corrélés, d’établir des scénarios exploités par exemple pour le calcul des risques.
Dans l’exemple qui suit, on génère une matrice 4×4 par le même procédé qu’auparavant, avec des 1 sur la diagonale et des nombres aléatoires compris entre 0.7 et 1 ailleurs, censés représenter des coefficients de corrélation (l’inconvénient de ce procédé est qu’il faut parfois le relancer pour obtenir une matrice définie positive, les valeurs aléatoires ne respectant aucune cohérence). La matrice obtenue est M.
 

 
numpy.fft fft → fast Fourier transform
 
Cette section sera brève: la transformation de Fourier concernant des domaines scientifiques comme la théorie du signal, ce n’est pas le package le plus recherché par les utilisateurs d’Excel. Cependant, Excel permet aussi de calculer la transformée discrète d’une fonction à partir d’un échantillon de 2n points de cette fonction(agorithme de Gauss/Cooley-Tukey) à partir du complément Utilitaire d’analyse se trouvant dans le groupe Analyse du ruban Données. Cet utilitaire fait partie du complément (Add-In) Analysis ToolPak. Certaines versions moins récentes de cet utilitaire ne permettent pas le calcul de la transformée inverse.
Ici encore, python propose des fonctions faciles à manipuler, sachant que les arguments de type complexe sont traitées comme des valeurs simples (la manipulation des nombres complexes dans Excel/VBA passe par le « constructeur » COMPLEX).
Dans l’exemple qui suit, la fonction fft calcule la transformée discrète de la fonction sinus (la transformée continue n’existe pas, la fonction sinus n’étant pas de carré intégrable) sur 512 (=29) points parcourant l’intervalle [0,2π]. On pourra utiliser la fonction linspace pour désigner les 512 abscisses.
Le résultat obtenu confirme la théorie: les fréquences significatives se réduisent à 2 « Dirac » opposés, de part et d’autre des points d’abscisses k*2π
 

 
La fonction ifft (transformée inverse) permet de retrouver la sinusoïde de départ

d=np.round(ifft(c))

Quelques mots sur scipy

Pour faire court, scipy est un package censé fournir toutes les fonctions avancées (algèbre, intégration, calcul complexe, optimisation,…) tandis que numpy devrait se cantonner à la manipulation des objets ndarray et fonctions de base. Nous venons de voir que le package numpy intègre lui aussi des modules avec des fonctions avancées (algèbre linéaire, transformée discrète de Fourier,…) car le type ndarray est compatible avec les fonctions de scipy.
En pratique, scipy est plus complet et évolutif que numpy. Plus précisément, des sous-packages tels que scipy.linalg ou scipy.fftpack englobent et perfectionnent numpy.linalg et numpy.fft, mais scipy offre aussi une gamme de fonctionnalités très étendue dans le domaine des statistiques (scipy.stats) ou de l’intégration (scipy.integrate). Là encore, se reporter au tutoriel.
Même si cela sort du cadre de cette présentation, scipy permet aussi la programmation parallèle, c’est à dire de meilleures performances dans les calculs volumineux.Une fois la suite Anaconda installée, on procèdera comme pour l’installation de numpy en ligne de commande, à partir du même répertoire

pip install scipy

scipy.integrate

Ce package propose des fonctions calculant l’intégrale d’une fonction quelconque entre deux points (incluant +∞==np.fin et -∞==-np.fin). Cette intégrale peut être simple (quad), double (dblquad) ou triple (tplquad)
Le 1er argument est le nom de la fonction, les deux autres sont les bornes de l’intégrale. Ces fonctions renvoient un tuplet contenant la valeur (approchée) de l’intégrale, et un majorant de l’erreur estimée, en valeur absolue.Ex: calcul de
 

 
Ici, la définition de f tient sur une ligne, donc on peut raccourcir le code, sachant que f=lambda x:exp(-x)*sin(x)
 

La fonction dblquad prend 5 arguments (référence de la fonction + 2×2 bornes).
Si les bornes d’une intégrale dépend d’une des variables, comme dans


les deux derniers arguments doivent faire référence aux fonctions u et v (et non à des bornes fixes).

Ex: calcul de
 

 
Là encore, la fonction lambda permet de réduire tout le code calculant l’intégrale à une seule ligne

scipy.stats

La liste des traitements de toutes sortes, sur des distributions continues, discrètes ou des échantillons, est impressionnante. Le nombre de distributions concernées est lui aussi impressionnant, il suffit de consulter le tutoriel de référence.
Notons que scipy rend possible de créer des classes de variables continues ou discrètes, dérivant des classes mères rv_continuous ou rv_discrete, dans lesquelles les fonctions de base (probabilité cumulée _pdf, génération de valeurs aléatoire _rvs,…) peuvent être surchargées.