Aller au contenu principal

Nettoyer les données avec Pandas

Le nettoyage transforme un schéma observé en un schéma déclaré. Rendez cette transformation reproductible et les données rejetées visibles.

Pipeline

  1. Conservez les entrées brutes, ou leur emplacement immuable et leur provenance.
  2. Normalisez les noms de colonnes et les espaces manifestement superflus.
  3. Analysez les types avec des formats explicites et un comportement d'échec maîtrisé.
  4. Résolvez doublons et valeurs manquantes selon les règles métier.
  5. Validez clés, plages, catégories, unités et invariants entre colonnes.
  6. Produisez les données nettoyées ainsi qu'un rapport de qualité.
import pandas as pd

raw = pd.DataFrame({
"entity_id": [1, 1, 2],
"email": [" ADA@example.org ", "ada@example.org", "lin@example.org"],
"amount": ["10", "12", "bad"],
"occurred_at": ["2026-01-01", "2026-01-02", "invalid"],
"updated_at": pd.to_datetime(["2026-01-01", "2026-01-02", "2026-01-03"]),
"code": ["AB-01", "AB-02", "CD-03"],
})
clean = (
raw.rename(columns=str.strip)
.assign(
email=lambda x: x["email"].str.strip().str.lower(),
amount=lambda x: pd.to_numeric(x["amount"], errors="coerce"),
occurred_at=lambda x: pd.to_datetime(
x["occurred_at"], format="%Y-%m-%d", errors="coerce", utc=True
),
)
)

errors="coerce" convertit les échecs d'analyse en valeurs manquantes ; cela ne les rend pas acceptables. Comptez et examinez ces échecs avant de poursuivre.

L’étape suivante sépare les lignes rejetées avant dédoublonnage et validation. Ici, la ligne 2 est rejetée et l’enregistrement le plus récent de l’entité 1 est conservé, avec un montant de 12.

invalid = clean["amount"].isna() | clean["occurred_at"].isna()
rejected = raw.loc[invalid].copy()
clean = clean.loc[~invalid].copy()

Extraction de texte

Préférez les méthodes vectorisées sur les chaînes aux fonctions de rappel Python :

parts = clean["code"].str.extract(r"^(?P<prefix>[A-Z]+)-(?P<number>[0-9]+)\Z")
clean = clean.join(parts)

Les expressions régulières doivent décrire le format accepté, pas seulement trouver une sous-chaîne plausible. Conservez la colonne d'origine jusqu'à la réussite de la validation.

Doublons

Définissez la clé d'entité et l'ordre avant d'appeler drop_duplicates :

clean = (
clean.sort_values("updated_at", kind="stable")
.drop_duplicates(subset=["entity_id"], keep="last")
)

Il s'agit d'une règle métier. Consignez pourquoi la ligne conservée fait autorité.

Valider explicitement

assert clean["entity_id"].notna().all()
assert clean["entity_id"].is_unique
assert clean["amount"].notna().all()
assert clean["amount"].ge(0).all()

Aux frontières de production, préférez un schéma ou une couche de validation réutilisable à un ensemble d'assertions ponctuelles.

Préserver le sens de la validation

Pour distinguer les erreurs de conversion des absences initiales, comparez notna() sur la colonne brute à isna() sur la colonne convertie, avec le même index et avant filtrage. L’extraction renvoie deux colonnes textuelles : convertissez explicitement number pour calculer. [0-9] limite les chiffres à ASCII et \Z impose la fin réelle de la chaîne.

Mettre toute l’adresse électronique en minuscules suppose une règle applicative insensible à la casse, pas une règle universelle d’identité des adresses. Ici, utc=True interprète les dates comme minuit UTC, pas minuit local. Le dédoublonnage suppose des dates de mise à jour converties et présentes ; un tri stable garde la dernière ligne d’entrée en cas d’égalité, seulement si cette règle de départage convient. Python -O désactive les assertions ; les contrôles obligatoires doivent lever des exceptions explicites.

Sources

Explorer les liensOuvrir le réseau