Aller au contenu
Data (pandas / numpy)

pandas — groupby et agrégation

groupby découpe un tableau par catégorie puis agrège chaque groupe, exactement comme GROUP BY en SQL. On s'en sert pour un CA par ville, une moyenne par classe ou un nombre de connexions par jour.

  • groupby
  • agg
  • agrégation
  • GROUP BY
  • transform
  • pivot_table
  • HAVING

Syntaxe

Modèle
df.groupby("cle")["col"].sum()df.groupby(["cle1", "cle2"]).agg(    total=("col", "sum"), nb=("col", "size"), moyenne=("col", "mean"),).reset_index()df.groupby("cle")["col"].transform("sum")     # une valeur par ligne d'origine

Exemple

Exemple concret
import pandas as pdventes = pd.DataFrame({    "ville": ["Lyon", "Paris", "Lyon", "Paris", "Lille"],    "montant": [120.0, 300.0, 80.0, 150.0, 60.0],})print(ventes.groupby("ville")["montant"].sum().to_dict())# → {'Lille': 60.0, 'Lyon': 200.0, 'Paris': 450.0}bilan = (ventes.groupby("ville")               .agg(ca=("montant", "sum"), nb=("montant", "size"), panier=("montant", "mean"))               .reset_index()               .sort_values("ca", ascending=False))print(bilan["ville"].tolist(), bilan["panier"].tolist())# → ['Paris', 'Lyon', 'Lille'] [225.0, 100.0, 60.0]print(bilan[bilan["ca"] > 100]["ville"].tolist())   # → ['Paris', 'Lyon']ventes["part_ville"] = ventes["montant"] / ventes.groupby("ville")["montant"].transform("sum")print(ventes["part_ville"].round(2).tolist())       # → [0.6, 0.67, 0.4, 0.33, 1.0]

À retenir

  1. L'agrégation nommée agg(nom=("colonne", "fonction")) produit des colonnes de sortie claires, sans index à plusieurs niveaux ; reset_index() remet la clé de groupe en colonne ordinaire.
  2. Le filtre après agrégation, l'équivalent de HAVING en SQL, s'applique au résultat : bilan[bilan["ca"] > 100].
  3. transform renvoie une valeur par ligne d'origine (ici le total de la ville répété) : c'est l'outil pour calculer une part ou un écart à la moyenne du groupe.
  4. Piège : size compte toutes les lignes, count seulement les valeurs non manquantes de la colonne. Et par défaut, groupby écarte les lignes dont la clé est manquante ; passez dropna=False pour les garder.
  5. Pour un tableau croisé (villes en lignes, mois en colonnes), utilisez pd.pivot_table(df, index="ville", columns="mois", values="montant", aggfunc="sum").

Voir aussi