NumPy : une très courte introduction

Cette page donne quelques éléments sur l'utilsation des array du module NumPy. Bien entendu ces exemples ne sont pas exhaustifs et ne reflètent pas toute la richesse des modules NumPy et SciPy. Un tutoriel est disponnible directement sur la page de la documentation de NumPy : Quickstart tutorial.

Des liens importants :

NumPy et SciPy contiennent également les fonctions ou constantes du module math de python.

Liste python ou array NumPy ?

Nous avons vu précédemment que les listes python sont dynamiques (leur taille n'est pas fixe) et elles peuvent contenir tout types d'éléments : entiers, flottants, chaînes de caractères ... Ce comportement donne aux listes une grande flexibilité et les rends très commode à utiliser au détriment d'une perte d'efficacité. C'est ce dernier point auquel NumPy tente de répondre avec les array.

Quelques spécificités des array :

  • la taille d'un array est fixe
  • un array ne contient qu'un seul type de données
  • un array ne contient que la valeur et non l'objet en entier

Ces spécificités permettent une plus grande efficacité lors du parcours d'un array ou lors d'opérations impliquant des array.

Numpy ou Scipy ?

Avant de commencer voici un petit commentaire sur la différence entre NumPy et SciPy. Ce texte est extrait de la FAQ scipy :

Idéalement, NumPy ne devrait contenir que la classe array, avec les méthodes permettant de réaliser des opérations de base sur ces arrays tandis que SciPy contiendrait toutes les fonctions numériques qui utilisent ces arrays.

Dans un soucis de compatibilité NumPy conserve les méthodes historiquement contenues par lui-même ou ses prédécesseurs. Les versions les plus récentes de ces méthodes ou les nouveautés sont par contre présentes dans SciPy. De plus, SciPy contient entièrement NumPy.

Lequel dois-je utiliser ?

  • NumPy, si vous souhaitez simplement utiliser les array
  • SciPy, pour les méthodes les plus avancées

Les exemples

Importer les modules :

Habituellement on importe NumPy et SciPy avec des alias pour faciliter leur utilisation.

import numpy as np
import scipy as sp

Créer un array

# à partir d'une liste :
>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
# avec la fonction arange
>>> r = np.arange(2, 10)
>>> r
array([2, 3, 4, 5, 6, 7, 8, 9])
>>> r = np.arange(2, 10, dtype="float64")
>>> r
array([ 2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.])
# avec des méthodes de numpy
>>> un = np.ones(4)
>>> un
array([ 1.,  1.,  1.,  1.])
>>> nul = np.zeros(3)
>>> nul
array([ 0.,  0.,  0.])

Quel type de données

Comme on l'a dit plus haut, contrairement aux listes, les array contiennent un seul type de données :

>>> a.dtype
dtype('int64')
>>> un.dtype
dtype('float64')

Les dimensions (forme) d'un array

>>> a = np.arange(2, 10, dtype="int")
>>> a
array([2, 3, 4, 5, 6, 7, 8, 9])
>>> a.shape
(8,)
>>> b = a.reshape(2,4)
>>> b
array([[2, 3, 4, 5],
       [6, 7, 8, 9]])
>>> b.shape
(2, 4)

Algèbre

Un avantage des array est que les opérateurs mathématiques s'appliquent à tous ses éléments. Cela permet, par exemple, d'additioner des vecteurs ou des matrices :

>>> a = np.ones(3)
>>> y = np.array([0, 1, 0])
>>> x = np.array([1, 0, 0])
>>> a
array([ 1.,  1.,  1.])
>>> x
array([1, 0, 0])
>>> y
array([0, 1, 0])
>>> x + y
array([1, 1, 0])
>>> a - x - y
array([ 0.,  0.,  1.])
>>> a * x
array([ 1.,  0.,  0.])

On peut calculer des sommes des produits scalaires, vectoriels ...

# produit scalaire
>>> np.dot(a, x)
1.0
>>> np.cross(x, y)
array([0, 0, 1])
# somme des éléments du array
>>> a.sum()
3.0
>>> b = np.arange(2, 10).reshape(2, 4)
>>> b
array([[2, 3, 4, 5],
       [6, 7, 8, 9]])
>>> b.sum(axis=0)
array([ 8, 10, 12, 14])
>>> b.sum(axis=1)
array([14, 30])
# produit matriciel
>>> np.dot(b, np.array([0, 1, 0, 0]))
array([3, 7])

Sélections de lignes, colonnes

Attention : En python les indices commencent toujours à 0.

>>> r = np.random.random((4, 5))
>>> r
array([[ 0.04159733,  0.66203517,  0.75505845,  0.30373412,  0.41154307],
       [ 0.19002609,  0.56761014,  0.54222685,  0.29554527,  0.05386348],
       [ 0.40999777,  0.28028108,  0.90805301,  0.67776604,  0.55878456],
       [ 0.30443061,  0.54716066,  0.03860554,  0.3677808 ,  0.39150167]])
# une valeur
>>> r[0, 0]
0.04159733383275166
>>> r[-1, -2]
0.36778080344490116
>>> r[1, 2]
0.54222685348487565
# ligne 2
>>> r[1,:]
array([ 0.19002609,  0.56761014,  0.54222685,  0.29554527,  0.05386348])
# colonne 3
>>> r[:,2]
array([ 0.75505845,  0.54222685,  0.90805301,  0.03860554])

Un filtre rapide avec where

>>> np.where(r > 0.5)
(array([0, 0, 1, 1, 2, 2, 2, 3]), array([1, 2, 1, 2, 2, 3, 4, 1]))

Ici, on récupère les indices (ligne, colonne) des éléments qui satisfont la condition.

>>> np.where(r > 0.5, r, -r)
array([[-0.04159733,  0.66203517,  0.75505845, -0.30373412, -0.41154307],
       [-0.19002609,  0.56761014,  0.54222685, -0.29554527, -0.05386348],
       [-0.40999777, -0.28028108,  0.90805301,  0.67776604,  0.55878456],
       [-0.30443061,  0.54716066, -0.03860554, -0.3677808 , -0.39150167]])

Dans ce second cas, on récupère la valeur de r si la condition est satisfaite et la valeur de -r sinon.

Lecture, écriture d'un fichier avec NumPy

Reprennons le fichier vu précédemment :

# titre du fichier
1. 2.1
2. 2.9
3. 4.2
4. 5.05
5. 5.85
6. 6.95
7. 8.1
8. 9.
9. 10.2
10. 10.9

La fonction loadtxt permet de lire facilement un fichier avec des données en colonne ou de type csv :

>>> data = np.loadtxt("data/donnees.dat", comments="#")
>>> print(data)
[[  1.     2.1 ]
 [  2.     2.9 ]
 [  3.     4.2 ]
 [  4.     5.05]
 [  5.     5.85]
 [  6.     6.95]
 [  7.     8.1 ]
 [  8.     9.  ]
 [  9.    10.2 ]
 [ 10.    10.9 ]]
>>> x, y = np.loadtxt("data/donnees.dat", unpack=True)
>>> print(x)
[  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.]
>>> print(y)
[  2.1    2.9    4.2    5.05   5.85   6.95   8.1    9.    10.2   10.9 ]

On pourra utiliser les options suivantes :

  • comments="&", saute les lignes démarrant par "&"
  • usecols=(1, 3) : lire les colonnes 1 et 3
  • skiprows=4 : saute les 4 premières lignes

Pour écrire un fichier, on pourra utiliser np.savetxt(), voici un exemple fonctionnel :

>>> header = "# titre du fichier\n"
>>> header += "# column 1 : ....\n"
>>> header += "# column 2 : ....\n"
...
>>> n = len(datas[0])
>>> X = [np.array(vec).reshape(n, 1) for vec in datas]
>>> X = np.concatenate(tuple(X), axis=1)
>>> np.savetxt("mesdonnees.dat", X, fmt="%10.5f", header=header)
  • le premier argument est le nom du fichier
  • header sera imprimé au début du fichier
  • fmt est le format qui sera utilisé pour imprimer les nombres
  • X est un array
    • Pour construire X on utilise concatenate permettant de combiner plusieurs array
    • On met axis=1 pour ajouter successivement des colonnes
    • Les array doivent avoir une forme (n, 1)

Conclusion

Cette très courte introduction donne un apperçu de ce qu'on peut faire avec les array. L'utilisation de NumPy et SciPy dépend ensutie de ce qu'on veut en faire. De très nombreux modules et fonctions sont disponnibles en voici quelques uns :

  • [SciPy] Le module linalg pour linear alegebra
  • [SciPy] le module integrate pour l'intégration numérique
  • [SciPy] le module constante contient de nombreuses constantes : h, c, R ...
  • [NumPy] contient également une classe np.matrix qui fonctionne "à la matlab".

Le site de SciPy regorge de ressources sur le sujet. On y trouve, entre autre, ce cours sur SciPy.

results matching ""

    No results matching ""