Devmind.
Menu

Apprendre, à votre rythme

Tous les cursus sont accessibles sans compte.

Chapitre 11 / Pratique

Atelier : nettoyer un CSV sale

Rendre un nettoyage rejouable et tracé.

◷ 45 minutesTravail sur votre machine

Énoncé

Reprenez data/colis_bruts.csv de la leçon « Données fil rouge ». Écrivez clean.py qui produit data/colis_propres.csv et data/rapport_nettoyage.txt en un seul appel. Commencez par compter les lignes, les commande_id distincts, les poids manquants et les unités. Puis retirez les doublons exacts, convertissez tous les poids présents en kilogrammes et vérifiez qu'aucun poids présent n'est négatif ou nul.

Contraintes

Ne modifiez jamais le fichier brut. Conservez les valeurs de poids manquantes : la médiane doit être apprise uniquement sur le train, plus tard, dans un pipeline. Ne retirez aucune ligne pour son prix ou son retard. Le rapport doit donner les comptes avant/après, le nombre de conversions grammes → kilogrammes et les règles appliquées. Exécutez python clean.py deux fois : les deux sorties doivent être identiques.

Indices

drop_duplicates() enlève les copies exactes ; duplicated("commande_id") permet de vérifier l'unicité restante. Avec pd.to_numeric, les cases vides lues par read_csv restent manquantes. Utilisez un masque unite_poids == "g" pour diviser par 1 000. sort_values("commande_id") stabilise l'ordre de sortie.

Correction disponibleCherchez d’abord par vous-même.Voir la correction

Correction

Placez ce code dans clean.py, à côté du dossier data, puis lancez python clean.py :

from pathlib import Path
import pandas as pd

data = Path("data")
brut = pd.read_csv(data / "colis_bruts.csv")
assert set(brut["unite_poids"]) == {"g", "kg"}

nb_doublons = int(brut.duplicated().sum())
nb_manquants = int(brut["poids_valeur"].isna().sum())
propre = brut.drop_duplicates().copy()
assert propre["commande_id"].is_unique

propre["poids_kg"] = pd.to_numeric(propre["poids_valeur"])
en_grammes = propre["unite_poids"].eq("g")
propre.loc[en_grammes, "poids_kg"] /= 1000
assert (propre["poids_kg"].dropna() > 0).all()

propre = propre.drop(columns=["poids_valeur", "unite_poids"])
propre = propre.sort_values("commande_id").reset_index(drop=True)
propre.to_csv(data / "colis_propres.csv", index=False)

rapport = (
    f"lignes brutes : {len(brut)}\n"
    f"doublons exacts retirés : {nb_doublons}\n"
    f"lignes propres : {len(propre)}\n"
    f"poids manquants dans le brut : {nb_manquants}\n"
    f"poids manquants conservés : {propre['poids_kg'].isna().sum()}\n"
    f"poids convertis de g en kg : {en_grammes.sum()}\n"
    "règles : doublons exacts retirés ; unités converties ; aucune imputation\n"
)
(data / "rapport_nettoyage.txt").write_text(rapport, encoding="utf-8")
print(rapport)

Sur le fichier fourni, il reste 320 commandes après retrait de 5 doublons. Le rapport ne doit annoncer aucune imputation. Une valeur manquante restera visible dans colis_propres.csv ; la préparer sans fuite sera la responsabilité du pipeline d'entraînement. Si le contrôle d'unicité échoue sur un autre jeu, examinez les lignes conflictuelles au lieu de garder arbitrairement la première.