Aller au contenu principal

NumPy

Un ndarray possède un dtype fixe décrivant chaque emplacement ; une forme (2, 3) signifie deux lignes et trois colonnes, pas deux listes Python indépendantes. Cette référence couvre les tableaux denses en mémoire et suppose que vous connaissez l’indexation et le découpage en tranches de Python. Les API utilisées existent dans NumPy 1.26 et 2.x ; précisez les types de largeur fixe si la représentation importe, car largeur entière inférée et promotions peuvent varier. Les valeurs des tableaux d’entiers ont une plage finie et peuvent déborder.

Site officiel​

Importer NumPy​

import numpy as np

Création de tableaux​

Créer des tableaux​

# One-dimensional array
a = np.array([1, 2, 3], dtype=np.int64)
print(a)
# [1 2 3]
print(a.ndim)
# 1

# Multi-dimensional array
b = np.array([[1,2,3],[4,5,6]])
print(b)
# [[1 2 3]
# [4 5 6]]

Attributs des tableaux​

# Shape of array
b.shape # (2, 3)

# Type of elements in the array
a.dtype # dtype('int64')

# Floats in numpy arrays
c = np.array([2.2, 5, 1.1])
print(c.dtype.name)
# float64
print(c)
# [2.2 5. 1.1]

Créer des tableaux avec des valeurs initiales​

# Array of zeros
d = np.zeros((2,3))
print(d)
# [[0. 0. 0.]
# [0. 0. 0.]]

# Array of ones
e = np.ones((2,3))
print(e)
# [[1. 1. 1.]
# [1. 1. 1.]]

# Array with random numbers
rng = np.random.default_rng(42)
print(rng.random((2, 3)))
# [[0.77395605 0.43887844 0.85859792]
# [0.69736803 0.09417735 0.97562235]]

Créer des séquences​

# Sequence of numbers
f = np.arange(10, 50, 2)
print(f)
# [10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48]

# Sequence of floats
print(np.linspace(0, 2, 15))
# [0. 0.14285714 0.28571429 0.42857143 0.57142857 0.71428571
# 0.85714286 1. 1.14285714 1.28571429 1.42857143 1.57142857
# 1.71428571 1.85714286 2. ]

Formes, axes et diffusion​

La diffusion compare les dimensions depuis la droite : les deux dimensions de chaque paire doivent être égales ou l’une d’elles doit valoir 1 ; les dimensions initiales absentes valent 1. Ainsi (2, 3) + (3,) ajoute un vecteur à chaque ligne, tandis que (2, 3) + (2,) échoue. Transformez ce dernier en (2, 1) pour ajouter une valeur par ligne. La diffusion évite de copier les entrées répétées, mais les sorties et intermédiaires occupent de la mémoire.

L’axis d’une réduction est la dimension supprimée : axis=0 réduit les lignes et laisse une valeur par colonne ; axis=1 réduit les colonnes et laisse une valeur par ligne. keepdims=True conserve un axe de taille 1 pour une diffusion ultérieure. Le remodelage conserve le nombre d’éléments ; une seule dimension -1 peut être inférée. Un vecteur unidimensionnel n’a pas d’orientation ligne/colonne : .T ne change pas sa forme. Utilisez v[:, None] pour une colonne.

x = np.arange(6).reshape(2, 3)
assert (x + np.array([10, 20, 30])).tolist() == [[10, 21, 32], [13, 24, 35]]
assert x.sum(axis=0).tolist() == [3, 5, 7]
assert x.sum(axis=1).tolist() == [3, 12]
centered = x - x.mean(axis=1, keepdims=True)
assert centered.tolist() == [[-1.0, 0.0, 1.0], [-1.0, 0.0, 1.0]]
assert x.reshape(-1).shape == (6,)
Un vecteur de forme (3,) est ajouté à chaque ligne d’un tableau de forme (4, 3).Voir l’image en grand

Les trois positions du dernier axe s’alignent ; le vecteur s’applique donc aux quatre lignes. Les lignes pâles répétées illustrent le calcul ; la diffusion n’exige pas de copier physiquement le vecteur d’entrée en quatre lignes. Comparez avec l’exemple à deux lignes ci-dessus.

Opérations sur les tableaux​

Opérations arithmétiques​

# Creating arrays
a = np.array([10,20,30,40])
b = np.array([1, 2, 3, 4])

# Elementwise operations
print(a - b)
# [ 9 18 27 36]
print(a * b)
# [ 10 40 90 160]

# Converting Fahrenheit to Celsius
fahrenheit = np.array([0, -10, -5, -15, 0])
celsius = (fahrenheit - 32) * (5/9)
print(celsius)
# [-17.77777778 -23.33333333 -20.55555556 -26.11111111 -17.77777778]

Tableaux booléens​

# Boolean array example
print(celsius > -20)
# [ True False False False True]
print(celsius % 2 == 0)
# [False False False False False]

Opérations matricielles​

A = np.array([[1,1],[0,1]])
B = np.array([[2,0],[3,4]])

# Elementwise product
print(A * B)
# [[2 0]
# [0 4]]

# Matrix product
print(A @ B)
# [[5 4]
# [3 4]]

Conversion ascendante de type​

array1 = np.array([[1, 2, 3], [4, 5, 6]])
array2 = np.array([[7.1, 8.2, 9.1], [10.4, 11.2, 12.3]])

# Addition of arrays
array3 = array1 + array2
print(array3)
# [[ 8.1 10.2 12.1]
# [14.4 16.2 18.3]]
print(array3.dtype)
# float64

Fonctions d’agrégation​

# Sum, max, min, and mean
print(array3.sum())
# 79.3
print(array3.max())
# 18.3
print(array3.min())
# 8.1
print(array3.mean())
# 13.216666666666667

# Aggregation on 2D arrays
b = np.arange(1, 16, 1).reshape(3, 5)
print(b)
# [[ 1 2 3 4 5]
# [ 6 7 8 9 10]
# [11 12 13 14 15]]

Indexation, découpage et itération​

Indexation​

# One-dimensional array
a = np.array([1, 3, 5, 7])
print(a[2])
# 5

# Multidimensional array
a = np.array([[1, 2], [3, 4], [5, 6]])
print(a[1, 1])
# 4
print(np.array([a[0, 0], a[1, 1], a[2, 1]]))
# [1 4 6]
print(a[[0, 1, 2], [0, 1, 1]])
# [1 4 6]

Indexation booléenne​

# Boolean array example
print(a > 5)
# [[False False]
# [False False]
# [False True]]
print(a[a > 5])
# [6]

Découpage​

# One-dimensional slicing
a = np.array([0, 1, 2, 3, 4, 5])
print(a[:3])
# [0 1 2]
print(a[2:4])
# [2 3]

# Multidimensional slicing
a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(a[:2])
# [[1 2 3 4]
# [5 6 7 8]]
print(a[:2, 1:3])
# [[2 3]
# [6 7]]

Les tranches partagent généralement la mémoire​

# Basic slicing usually returns a view that shares memory with the source.
sub_array = a[:2, 1:3]
sub_array[0, 0] = 50
print(sub_array[0, 0])
# 50
print(a[0, 1])
# 50
print(np.shares_memory(a, sub_array))
# True

# Use copy() when the result must be independent.
independent = a[:2, 1:3].copy()

L’indexation avancée avec des tableaux d’entiers ou booléens renvoie généralement une copie à la place. Utilisez np.shares_memory() lorsque cette distinction importe.

Charger un petit jeu de données délimité​

Un exemple autonome évite de dépendre d’un fichier téléchargé particulier ou d’un schéma de colonnes précis :

from io import StringIO

csv_data = StringIO("""height,score
1.70,82
1.82,91
1.65,76
""")
records = np.genfromtxt(csv_data, delimiter=",", names=True)

print(records.dtype.names)
# ('height', 'score')
print(records["score"].mean())
# 83.0

Copies, comparaison numérique et reproductibilité​

Le contrat copie/vue est précis : les tranches de base partagent les données ; une lecture par tableau d’entiers ou de booléens crée une copie. L’affectation directe x[x < 0] = 0 modifie pourtant bien x. reshape renvoie une vue si possible, sinon une copie ; flatten() copie toujours. a + b crée normalement un résultat, tandis que a += b écrit dans a sans pouvoir changer implicitement son dtype pour accueillir des flottants. En multiplication matricielle 2-D, (m, k) @ (k, n) donne (m, n) ; * agit élément par élément.

== produit un tableau booléen, pas un verdict unique. np.array_equal vérifie valeurs exactes et forme. Pour les valeurs flottantes finies, np.allclose teste abs(a-b) <= atol + rtol*abs(b) ; les infinis de même signe aux positions correspondantes sont considérés comme égaux, tandis qu’une valeur finie n’est pas considérée comme proche d’un infini. Choisissez les tolérances selon les unités et la précision du problème. La diffusion étant permise, vérifiez la forme séparément si nécessaire. Les NaN restent inégaux sauf avec equal_nan=True. Les réductions comme sum propagent NaN ; nansum l’ignore, ce qui change la règle de données manquantes. Les exemples de Nombres flottants et calcul stable justifient ce choix et expliquent l’effet de l’ordre de sommation.

arange exclut normalement la borne finale, mais les arrondis en virgule flottante peuvent faire apparaître cette borne dans le résultat ou conduire à une dernière valeur qui la dépasse ; linspace fixe un nombre de points et inclut la borne finale par défaut. L’exemple aléatoire emploie un Generator local avec graine : le relancer reprend le même flux dans un environnement identique. Pour une reproduction exacte à long terme, notez version NumPy et générateur ; la graine seule ne garantit pas un flux identique entre versions.

expected = np.array([0.3])
actual = np.array([0.1]) + 0.2
assert not np.array_equal(actual, expected)
assert actual.shape == expected.shape
assert np.allclose(actual, expected, rtol=0, atol=1e-15)

Documentation​

Documentation NumPy — manuel stable actuel

NumPy : les bases absolues pour débutants

Explorer les liensOuvrir le réseau