Skip to content

Pandas Data Cleaning : workflow pratique

Updated on

Des données sales bloquent l’analyse très tôt. Des fillna ou remplacements ponctuels masquent des problèmes réels : mauvais types, doublons silencieux ou outliers qui biaisent les métriques.

Cadre PAS :

  • Problème : Types mixtes, valeurs manquantes et doublons cassent les joins et faussent les stats.
  • Agiter : Les correctifs ponctuels cachent les soucis jusqu’à la fin du projet et génèrent du rework.
  • Solution : Un checklist réutilisable : standardiser les types, traiter les nuls intentionnellement, gérer les outliers, dédupliquer et valider avant export.

Workflow en bref

ÉtapeActionExemple
1. ProfilerColonnes, nuls, uniquesdf.info(), df.describe(include="all")
2. Normaliser les colonnesNettoyer noms/textedf.columns = df.columns.str.strip().str.lower()
3. Corriger les typesto_datetime, to_numeric, astype("category")df["date"] = pd.to_datetime(df["date"], errors="coerce")
4. Gérer les manquantsSupprimer ou remplirdf["age"] = df["age"].fillna(df["age"].median())
5. Gérer les outliersCapper ou marquerdf["rev_cap"] = df["revenue"].clip(upper=df["revenue"].quantile(0.99))
6. DédupliquerRetirer doublons exacts/partielsdf.drop_duplicates(subset=["id", "date"], keep="last")
7. ValiderImposer plages/catégoriesassert df["score"].between(0,100).all()

1) Profiler rapidement

summary = {
    "rows": len(df),
    "columns": df.shape[1],
    "nulls": df.isna().sum(),
    "unique_counts": df.nunique(),
}
  • Détecter tôt les types mixtes (df.info()).
  • Vérifier les distributions via df.describe(percentiles=[0.01,0.99]).

2) Normaliser colonnes et texte

df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
df["country"] = df["country"].str.strip().str.title()
  • Des noms standards simplifient les joins et le code.
  • Pour des caractères étranges : .str.normalize("NFKC").

3) Corriger les types

df["date"] = pd.to_datetime(df["date"], errors="coerce", utc=True)
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
df["segment"] = df["segment"].astype("category")
  • errors="coerce" rend visibles les valeurs incorrectes (NaT/NaN).
  • convert_dtypes() applique des types nullable et économes en mémoire.

4) Traiter les valeurs manquantes

df["age"] = df["age"].fillna(df["age"].median())
df["city"] = df["city"].fillna("Unknown")
df = df.dropna(subset=["id"])  # clé obligatoire
  • Décider par colonne : numérique → médiane/moyenne ; catégoriel → mode/placeholder.
  • Garder le signal avec un flag : df["age_imputed"] = df["age"].isna().

5) Traiter les outliers

upper = df["revenue"].quantile(0.99)
lower = df["revenue"].quantile(0.01)
df["revenue_capped"] = df["revenue"].clip(lower=lower, upper=upper)
  • Pour des ratios, filtrez via z-score : abs(z) < 3.
  • En finance, capper plutôt que supprimer pour conserver les comptes.

6) Dédupliquer en sécurité

df = df.drop_duplicates(subset=["id", "date"], keep="last")
  • Vérifier la clé d’unicité : assert df.duplicated(["id"]).sum() == 0.
  • Pour du flou, normaliser d’abord (e-mails en minuscules, etc.).

7) Valider avant export

assert df["score"].between(0, 100).all()
valid_segments = {"basic", "pro", "enterprise"}
assert df["segment"].isin(valid_segments).all()
  • En tests, utilisez pd.testing.assert_frame_equal pour comparer les sorties.
  • Ajoutez des checks légers (lignes/nuls) dans les pipelines pour capter les régressions.

Mini pipeline de bout en bout

def clean(df):
    df = df.copy()
    df.columns = df.columns.str.strip().str.lower()
    df["date"] = pd.to_datetime(df["date"], errors="coerce")
    df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
    df["amount"] = df["amount"].fillna(df["amount"].median())
    df["segment"] = df["segment"].fillna("unknown").str.lower()
    df = df.dropna(subset=["id"])
    df = df.drop_duplicates(subset=["id", "date"], keep="last")
    assert df["amount"].ge(0).all()
    return df
  • Copier d’abord pour ne pas muter l’entrée.
  • Avec df.pipe(clean), le pipeline reste lisible.

Guides liés


Points clés

  • Standardiser les noms, imposer les types, traiter les nuls avec intention.
  • Capper ou marquer les outliers plutôt que supprimer silencieusement.
  • Valider clés et plages avant d’envoyer vers la BI ou l’analytique.