pandas : des données brutes au tableau propre
Étape 2 : lire, nettoyer, transformer et agréger des données réelles, là où se joue la qualité d'un modèle.
Dans un vrai projet, on passe bien plus de temps à préparer les données qu’à entraîner le modèle. pandas est l’outil de cette préparation : lire, nettoyer, transformer, agréger. Un modèle entraîné sur des données sales donne des résultats faux, avec beaucoup d’assurance.
Series et DataFrame
Une Series est une colonne étiquetée, un DataFrame un tableau de colonnes qui partagent le même index. Chaque colonne est un tableau NumPy : tout ce qui a été vu à l’étape précédente s’applique.
import pandas as pd
df = pd.read_csv("ventes.csv", parse_dates=["date"])
df.shape # (lignes, colonnes)
df.head() # les 5 premières lignes
df.info() # types et valeurs manquantes, colonne par colonne
df.describe() # statistiques des colonnes numériques
info() et describe() sont les deux premières commandes à lancer sur n’importe quel jeu de données. Elles révèlent la moitié des problèmes.
Sélectionner et filtrer
df["montant"] # une colonne (Series)
df[["client", "montant"]] # plusieurs colonnes (DataFrame)
df.loc[df["montant"] > 100, "client"] # filtre + colonne, par étiquettes
df.iloc[:10, :3] # par positions
grosses_ventes = df.query("montant > 100 and pays == 'BF'")
loc travaille avec des étiquettes, iloc avec des positions. Les confondre est une source classique de bugs silencieux.
Nettoyer
df.isna().sum() # valeurs manquantes par colonne
df = df.drop_duplicates()
df["montant"] = df["montant"].fillna(df["montant"].median())
df["pays"] = df["pays"].str.strip().str.upper()
df = df[df["montant"] >= 0] # valeurs aberrantes
Pour les valeurs manquantes, pas de règle universelle : supprimer la ligne, remplir par la médiane, ou créer une colonne « était manquant ». Le bon choix dépend du pourquoi de l’absence, et c’est une vraie décision, pas un détail technique.
Transformer : créer des variables
C’est ici que la connaissance du métier fait la différence entre un modèle moyen et un bon modèle.
df["mois"] = df["date"].dt.month
df["jour_semaine"] = df["date"].dt.day_name()
df["panier_moyen"] = df["montant"] / df["nb_articles"]
df["gros_client"] = df["montant"] > df["montant"].quantile(0.9)
Agréger : groupby
par_pays = (
df.groupby("pays")
.agg(ca=("montant", "sum"), ventes=("montant", "size"), moyen=("montant", "mean"))
.sort_values("ca", ascending=False)
)
Le trio split / apply / combine répond à la majorité des questions métier : quel pays, quel mois, quel client ?
Joindre des tables
clients = pd.read_csv("clients.csv")
df = df.merge(clients, on="client_id", how="left")
Après chaque merge, vérifiez que le nombre de lignes n’a pas explosé : une clé dupliquée d’un côté multiplie les lignes de l’autre.
Visualiser pour comprendre
import matplotlib.pyplot as plt
df["montant"].hist(bins=50)
df.groupby("mois")["montant"].sum().plot(kind="bar")
plt.show()
Un histogramme montre en une seconde une distribution très asymétrique ou des valeurs impossibles, qu’aucune moyenne ne révèle.
Projet pour valider l’étape
Prendre le jeu de données Titanic sur Kaggle et produire un notebook propre qui :
- décrit chaque colonne et ses valeurs manquantes ;
- justifie une stratégie de remplissage pour l’âge ;
- crée au moins trois nouvelles variables (taille de la famille, titre extrait du nom…) ;
- répond par des
groupbyà : qui a survécu, selon la classe, le sexe, l’âge ?
Ce notebook sera réutilisé tel quel à l’étape suivante, pour entraîner le premier modèle.
Ressources
- 10 minutes to pandas, la documentation officielle.
- Le cours « Pandas » de Kaggle Learn.