Manipuler les nombres avec la bibliothèque standard Python : math et statistics

Série 05 – Calcul précis, synthèse claire

Le code numérique peut sembler simple, mais les erreurs d’arithmétique flottante ou la distinction entre population et échantillon peuvent modifier subtilement les résultats. Les modules math et statistics de la bibliothèque standard Python fournissent des outils robustes pour aborder ces situations.

Terrain de jeu mathématique et statistique

  • math : fonctions mathématiques, constantes, arrondis, combinatoire, comparaison de nombres flottants avec tolérance, sommes précises
  • statistics : moyenne, médiane, variance, etc. pour caractériser la distribution d’un jeu de données

1. math : boîte à outils mathématiques



1.1 Constantes et fonctions de base

import math

print(math.pi)     # Pi
print(math.e)      # Nombre d’Euler

print(math.sqrt(2))     # Racine carrée
print(math.pow(2, 10))  # Puissance (2**10 suffit souvent)

1.2 Arrondis : ceil, floor, trunc

Les résultats peuvent prêter à confusion surtout avec les nombres négatifs. Le tableau ci‑dessous clarifie les différences.

Valeur (x) math.ceil(x) math.floor(x) math.trunc(x)
3.7 4 3 3
-3.7 -3 -4 -3
import math

for x in [3.7, -3.7]:
    print(x, math.ceil(x), math.floor(x), math.trunc(x))
  • ceil : arrondit à l’entier supérieur (3.7→4, -3.7→-3)
  • floor : arrondit à l’entier inférieur (3.7→3, -3.7→-4)
  • trunc : tronque vers 0 (3.7→3, -3.7→-3)

1.3 Comparaison de flottants : isclose() plutôt que ==

import math

a = 0.1 + 0.2
b = 0.3
print(a == b)            # False (0.30000000000000004 != 0.3)
print(math.isclose(a, b))  # True

math.isclose(a, b, rel_tol=..., abs_tol=...) permet d’évaluer la proximité selon des tolérances relatives ou absolues.


1.4 Somme précise : fsum()

sum() est rapide mais peut accumuler des erreurs sur de grandes listes de flottants. math.fsum() calcule la somme de façon plus précise.

import math

values = [0.1] * 10_000
print(sum(values))
print(math.fsum(values))

1.5 Combinaisons et permutations : comb, perm

import math

print(math.comb(10, 3))  # Combinaisons de 3 éléments parmi 10
print(math.perm(10, 3))  # Permutations de 3 éléments parmi 10

2. statistics : fondamentaux de la synthèse de données

statistics calcule directement moyenne, médiane, variance, etc. à partir d’une liste ou d’un itérable.

2.1 Moyenne : mean vs fmean

import statistics as st

data = [10, 12, 13, 12, 100]
print(st.mean(data))   # Moyenne arithmétique
print(st.fmean(data))  # Moyenne calculée en virgule flottante (toujours un flottant)

2.2 Médiane / Mode : median, mode, multimode

import statistics as st

data = [10, 12, 13, 12, 100]
print(st.median(data))  # 12
print(st.mode(data))    # 12

Pour les données avec plusieurs modes, multimode() est plus sûr.

import statistics as st

data = [1, 1, 2, 2, 3]
print(st.multimode(data))  # [1, 2]

2.3 Variance / Écart type : population vs échantillon

import statistics as st

data = [10, 12, 13, 12, 100]

print(st.pvariance(data))  # Variance de la population
print(st.variance(data))   # Variance d’échantillon (n-1)

print(st.pstdev(data))     # Écart type de la population
print(st.stdev(data))      # Écart type d’échantillon

2.4 Moyenne pondérée : fmean(weights=...) (Python 3.11+)

Avant Python 3.11, on calculait manuellement. Depuis 3.11, statistics.fmean() accepte un argument weights.

import statistics as st

values = [80, 90, 100]
weights = [1, 2, 1]

# Python 3.11+: weighted_mean = st.fmean(values, weights=weights)
print(weighted_mean)

Version indépendante :

values = [80, 90, 100]
weights = [1, 2, 1]

weighted_mean = sum(v*w for v, w in zip(values, weights)) / sum(weights)
print(weighted_mean)

3. Trois précautions fréquentes en traitement numérique



3.1 float ne représente pas toujours exactement les décimales

C’est un problème d’arithmétique flottante, pas seulement de Python. Le module decimal est conçu pour l’arithmétique décimale exacte.

from decimal import Decimal

print(0.1 + 0.2)                   # 0.30000000000000004
print(Decimal("0.1") + Decimal("0.2"))  # Decimal('0.3')

3.2 Ne pas se fier uniquement à la moyenne, regarder aussi la médiane

Les valeurs aberrantes peuvent fausser la moyenne. Comparer moyenne et médiane donne une vision plus robuste.

3.3 Le calcul de la médiane peut devenir coûteux pour de grands jeux de données

La médiane nécessite souvent un tri. Pour de très grands ensembles, envisager des algorithmes plus efficaces ou des bibliothèques spécialisées.


4. Exemple concret : résumé de valeurs de capteur et gestion des erreurs cumulées

Voici un exemple de traitement simple d’une liste de mesures de capteur (flottants). On utilise statistics pour la tendance centrale et la dispersion, et math.fsum() pour une somme précise des écarts.

import math
import statistics as st

# Valeurs de capteur (le dernier, 21.5, est une valeur aberrante apparente)
readings = [20.1, 20.0, 20.2, 19.9, 20.1, 21.5]

# 1) Moyenne
print("fmean:", st.fmean(readings))   # fmean: 20.3

# 2) Médiane
print("median:", st.median(readings))   # median: 20.1

# 3) Écart type (échantillon)
print("stdev(sample):", st.stdev(readings))    # stdev(sample): 0.5966573556070519

# 4) Somme précise des écarts absolus par rapport à 20.0

diffs = [abs(x - 20.0) for x in readings]
print("sum abs diff:", math.fsum(diffs))     # sum abs diff: 2.0000000000000036

Avec ces quelques statistiques, on peut rapidement dire : « La plupart des mesures sont autour de 20, mais un point s’est détaché », ou « La dispersion est modérée ».


Articles connexes