209 lines
6.7 KiB
Markdown
209 lines
6.7 KiB
Markdown
---
|
||
title: Données avec Numpy
|
||
author: Steve Kossouho
|
||
---
|
||
|
||
# Création de données avec Numpy
|
||
|
||
----
|
||
|
||
## Tableaux Numpy
|
||
|
||
Numpy est une bibliothèque Python dont la principale fonctionnalité est codée dans le langage C. Il s'agit d'une structure de données nommée un `ndarray`, à savoir un tableau à **n-dimensions**.
|
||
|
||
Le stockage des données dans un tel tableau est beaucoup plus efficace que les listes Python, car les données d'un `ndarray` sont généralement des valeurs dont le type est l'un des types de base gérés nativement par un processeur moderne et stockables efficacement en mémoire (ex. entier 32 bits, entier 64 bits ou flottant 64 bits).
|
||
|
||
En plus d'être efficaces, ces tableaux se manipulent en utilisant la syntaxe standard de Python pour les listes, ce qui les rend très pratiques.
|
||
|
||
----
|
||
|
||
## Création d'un tableau Numpy
|
||
|
||
En règle générale, il est important de savoir générer un tableau avec Numpy, car cela peut occasionnellement servir pour certains calculs.
|
||
|
||
Pour créer un tableau à une dimension (l'équivalent d'une liste), c'est extrêmement simple :
|
||
|
||
```python {.numberLines}
|
||
import numpy as np
|
||
|
||
array1 = np.array([1, 2, 3]) # Crée un tableau 1D à partir d'une liste
|
||
print(array1)
|
||
```
|
||
|
||
Pour créer un tableau à deux dimensions, il suffit d'envoyer une liste contenant des éléments qui sont des listes (un pour chaque ligne) :
|
||
|
||
```python {.numberLines}
|
||
import numpy as np
|
||
|
||
array2 = np.array([[1, 2, 3], [4, 5, 6]]) # Crée un tableau 2D (matrice)
|
||
```
|
||
|
||
----
|
||
|
||
## Générer des tableaux avec Numpy
|
||
|
||
Nous avons vu qu'il est simple de créer manuellement des tableaux ou matrices depuis des listes Python, mais souvent,
|
||
il est intéressant de créer des données qui ont certaines propriétés, comme par exemple :
|
||
|
||
- Remplir une matrice de taille x avec des valeurs fixes
|
||
- Créer une matrice d'identité (carrée avec 1.0 en diagonale)
|
||
- Remplir une matrice de nombres aléatoires
|
||
- Remplir une matrice avec une suite arithmétique ou géométrique
|
||
|
||
----
|
||
|
||
### Séquence de nombres
|
||
|
||
Générer une suite arithmétique de nombres comme la fonction `range()`{.python} est possible grâce à la fonction `numpy.arange()`{.python} :
|
||
|
||
```python {.numberLines}
|
||
import numpy as np
|
||
|
||
range1 = np.arange(0, 10, 1) # De 0 à 9
|
||
range2 = np.arange(0, 10, 2) # De 2 en 2 de 0 à 8
|
||
range3 = np.arange(10, 0, -2) # De -2 en -2 de 10 à 2
|
||
```
|
||
|
||
----
|
||
|
||
### Séquence de valeurs équidistantes
|
||
|
||
On peut générer une suite de nombres uniformément disposés entre 2 valeurs incluses,
|
||
via la fonction "espace linéaire" `numpy.linspace()`{.python} :
|
||
|
||
```python {.numberLines}
|
||
import numpy as np
|
||
|
||
linspace1 = np.linspace(0, 10, num=5) # 0, 2.5, 5.0, 7.5 et 10.0
|
||
```
|
||
|
||
----
|
||
|
||
### Tableaux de nombres aléatoires
|
||
|
||
Vous pouvez générer des séquences ou matrices de nombres aléatoires avec plusieurs fonctions fournies par le module `numpy.random` :
|
||
|
||
```python {.numberLines}
|
||
import numpy as np
|
||
|
||
# Loi Gaussienne (normale), 3x3, centre à 5.0 et écart-type de 5.0
|
||
normal1 = np.random.normal(loc=5.0, scale=5.0, size=(3, 3))
|
||
# Loi de Pareto
|
||
pareto1 = np.random.pareto(10.0, size=100)
|
||
# Nombres pseudo-aléatoires entre 0 et 1 non inclus
|
||
basic1 = np.random.random(size=10)
|
||
```
|
||
|
||
----
|
||
|
||
### Tableaux préinitialisés
|
||
|
||
Vous pouvez très aisément générer des tableaux numpy contenant, au choix, des __zéros__, des __un__, une valeur constante
|
||
ou encore des matrices diagonales (identité notamment);
|
||
|
||
```python {.numberLines}
|
||
import numpy as np
|
||
from math import pi
|
||
|
||
# Tableau de 5 x 5 rempli de zéros
|
||
zeros = np.zeros((5, 5))
|
||
# Tableau de 9 x 4 rempli de 1
|
||
ones = np.ones((9, 4))
|
||
# Tableau de 6 x 2 rempli de Pi
|
||
pis = np.full((6, 2), pi)
|
||
# Matrice d'identité (carrée 3x3)
|
||
identity = np.identity(3)
|
||
```
|
||
|
||
----
|
||
|
||
### Générer des séquences de dates avec Pandas
|
||
|
||
Pandas propose de créer des __index__ d'objets date, dont le type est nommé `datetime64[ns]` (précision à la nanoseconde).
|
||
La fonction disponible pour ce faire est nommée `pandas.date_range`{.python} et s'utilise de deux façons :
|
||
|
||
```python {.numberLines}
|
||
import pandas as pd
|
||
|
||
# Générer un index contenant 4 dates équidistantes
|
||
# Les 4 dates contiennent celle de départ et celle de fin
|
||
date_index = pd.date_range("2024-01-01", "2024-12-31", periods=4)
|
||
```
|
||
|
||
Cette méthode permet de créer un __index__ de dates à intervalle constant. Il faut pour cela utiliser l'argument
|
||
`periods=` et y préciser le nombre de dates à obtenir dans l'index.
|
||
|
||
----
|
||
|
||
L'autre utilisation de la fonction `date_range()` consiste à générer un __index__ de dates,
|
||
non pas disposées à intervalles réguliers, mais disposées selon un motif; par exemple, il
|
||
est possible de générer un __index__ dans lequel on générera tous les lundi entre deux
|
||
dates. Pour cela il faudra utiliser l'argument `freq=` :
|
||
|
||
```python {.numberLines}
|
||
import pandas as pd
|
||
|
||
# Entre le 1er janvier et le premier mars inclus, générer tous les lundis
|
||
date_index = pd.date_range("2024-01-01", "2024-03-01", freq="W-MON") # weekly-monday
|
||
# Entre le 1er janvier et le premier mars inclus, générer un dimanche sur deux
|
||
date_index2 = pd.date_range("2024-01-01", "2024-03-01", freq="2W-SUN") # weekly-sunday
|
||
```
|
||
|
||
Il est possible de générer de nombreuses variations, qui sont documentées ici : [date_range:freq].
|
||
|
||
----
|
||
|
||
### Routines de création de tableaux
|
||
|
||
De très nombreuses fonctions de création de tableaux sont disponibles dans Numpy en sus des fonctions
|
||
présentées dans ce support. Elles sont présentées dans le document [Création de tableaux]
|
||
|
||
----
|
||
|
||
## Calcul avec les tableaux Numpy
|
||
|
||
Un des principaux intérêts des tableaux Numpy, outre leur consommation mémoire, est leur utilisation.
|
||
Il est simplement possible d'effectuer des modifications simples sur des tableaux, telles que :
|
||
|
||
- Calcul vectorisé
|
||
- Produit matriciel
|
||
- Agrégations (statistiques, arithmétique etc.)
|
||
|
||
----
|
||
|
||
### Opérations arithmétiques Numpy
|
||
|
||
Vous pouvez appliquer un calcul arithmétique à tous les éléments d'un tableau Numpy
|
||
sans avoir à effectuer de boucle `for`{.python} :
|
||
|
||
```python {.numberLines}
|
||
import numpy as np
|
||
|
||
numbers = np.array([1, 2, 3, 4, 5])
|
||
computed = numbers * 4 + 1.5 # Nouveau tableau où tous les éléments ont été modifiés
|
||
```
|
||
|
||
----
|
||
|
||
### Produit matriciel
|
||
|
||
Python 3.7 (2018) a introduit un nouvel opérateur destiné au produit matriciel : `@`{.python}
|
||
|
||
Cet opérateur peut être personnalisé par n'importe quelle classe via la méthode `__matmul__`{.python}.
|
||
La bibliothèque numpy est une des rares à l'utiliser.
|
||
|
||
```python {.numberLines}
|
||
import numpy as np
|
||
|
||
square = np.random.random(size=(3, 3))
|
||
identity = np.identity(3)
|
||
noop = square @ identity
|
||
print(square)
|
||
print(noop)
|
||
```
|
||
|
||
----
|
||
|
||
[date_range:freq]: https://pandas.pydata.org/docs/user_guide/timeseries.html#offset-aliases
|
||
[Création de tableaux]: https://numpy.org/doc/stable/reference/routines.array-creation.html
|