Transformation et filtrage avec GroupBy
Utilisez transform() pour ajouter des statistiques de groupe comme colonne et filter() pour ne conserver que les groupes satisfaisant une condition.
Transformation et filtrage avec GroupBy est une leçon Pandas & NumPy Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Pandas & NumPy Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Pandas & NumPy Academy comprend 4 leçons au total.
Au-delà de l’agrégation
Après avoir maîtrisé agg(), une question vient naturellement : que faire si vous souhaitez conserver toutes les lignes d’origine tout en les enrichissant avec des statistiques au niveau des groupes ? Ou ne conserver que les groupes qui remplissent une condition ? C’est là qu’interviennent transform() et filter(). Ces deux méthodes étendent les possibilités de GroupBy au-delà de la simple synthèse, jusqu’à la création de variables et à la sélection de données.
Comprendre transform()
transform() applique une fonction à chaque groupe et renvoie un résultat de la même forme que le DataFrame d’origine — une valeur par ligne d’origine. Le résultat du groupe est répercuté sur chaque ligne appartenant à ce groupe. Cette méthode est donc idéale pour ajouter des statistiques au niveau des groupes comme nouvelles colonnes sans modifier le nombre de lignes.
import pandas as pd
df = pd.DataFrame({
'dept': ['Eng', 'HR', 'Eng', 'HR', 'Eng'],
'salary': [90000, 60000, 95000, 62000, 88000]
})
# Add a column with each employee's department average salary
df['dept_avg'] = df.groupby('dept')['salary'].transform('mean')
print(df)
# dept salary dept_avg
# 0 Eng 90000 91000.000
# 1 HR 60000 61000.000
# 2 Eng 95000 91000.000
# 3 HR 62000 61000.000
# 4 Eng 88000 91000.000Cas d’utilisation courants de transform()
Parmi les applications courantes de transform() figurent l’ajout de la moyenne du groupe pour normaliser les valeurs, l’ajout de la somme du groupe pour calculer le pourcentage du total correspondant à chaque ligne et l’ajout du rang dans le groupe pour voir comment chaque élément se compare aux autres membres de son groupe. Tous ces cas préservent la forme et l’index d’origine, ce qui rend le résultat immédiatement utilisable avec les colonnes d’origine.
# Percentage of each employee's salary within their department total
df['pct_of_dept'] = (
df['salary'] / df.groupby('dept')['salary'].transform('sum') * 100
).round(1)
print(df[['dept', 'salary', 'pct_of_dept']])
# dept salary pct_of_dept
# Eng 90000 33.1
# HR 60000 49.2
# Eng 95000 34.9Utiliser une fonction personnalisée dans transform()
Tout comme agg(), transform() accepte n’importe quelle fonction appelable, en plus des noms sous forme de chaînes. La fonction reçoit une Series de valeurs correspondant à un groupe et doit renvoyer une Series de la même longueur, ou une valeur scalaire, qui est alors répercutée sur toutes les lignes. Le renvoi d’une valeur scalaire est le cas d’utilisation le plus courant ; renvoyer une Series d’une longueur différente déclenchera une erreur.
# Z-score normalisation within each department
def zscore(s):
return (s - s.mean()) / s.std()
df['salary_zscore'] = df.groupby('dept')['salary'].transform(zscore)
print(df[['dept', 'salary', 'salary_zscore']].round(2))
# dept salary salary_zscore
# Eng 90000 -0.51
# HR 60000 -0.71
# Eng 95000 1.03agg() et transform() comparés côte à côte
La différence essentielle est la suivante : agg() réduit le nombre de lignes, avec une ligne par groupe, tandis que transform() conserve le nombre de lignes, avec une ligne par ligne d’origine. Utilisez agg() pour créer un tableau récapitulatif. Utilisez transform() pour ajouter des informations au niveau du groupe comme nouvelle colonne de caractéristiques dans le DataFrame d’origine.
g = df.groupby('dept')['salary']
# agg: 2 rows (one per unique dept)
print(g.agg('mean'))
# dept
# Eng 91000.0
# HR 61000.0
# transform: 5 rows (one per original row)
print(g.transform('mean'))
# 0 91000.0
# 1 61000.0
# 2 91000.0
# 3 61000.0
# 4 91000.0Comprendre filter()
filter() conserve ou élimine des groupes entiers en fonction d’une fonction booléenne. Vous transmettez une fonction qui reçoit un sous-DataFrame correspondant à un groupe et renvoie True pour conserver le groupe ou False pour l’éliminer. Le résultat est un sous-ensemble du DataFrame d’origine contenant uniquement les lignes des groupes qui ont réussi le test.
df2 = pd.DataFrame({
'dept': ['Eng', 'HR', 'Eng', 'HR', 'Eng', 'Legal'],
'salary': [90000, 60000, 95000, 62000, 88000, 70000]
})
# Keep only departments with at least 2 employees
big_depts = df2.groupby('dept').filter(lambda g: len(g) >= 2)
print(big_depts)
# dept, salary rows: Eng(3) and HR(2) remain; Legal(1) droppedFiltrer selon une valeur agrégée du groupe
Une utilisation très courante de filter() consiste à conserver les groupes dont la valeur agrégée atteint un seuil. Par exemple, vous pouvez ne conserver que les services dont le salaire moyen dépasse un objectif, ou uniquement les catégories de produits dont les ventes totales dépassent un minimum. Cela vous permet d’éliminer les groupes à faible volume avant de poursuivre l’analyse.
# Keep only departments where average salary > 80000
high_paying = df2.groupby('dept').filter(
lambda g: g['salary'].mean() > 80000
)
print(high_paying)
# dept salary
# 0 Eng 90000
# 2 Eng 95000
# 4 Eng 88000
# (HR avg is 61000, filtered out)Combiner transform() et filter()
Vous pouvez appliquer transform() et filter() successivement pour enrichir vos données, puis les restreindre. Utilisez d’abord filter() pour supprimer les groupes non pertinents, puis appliquez transform() au résultat filtré afin d’ajouter des caractéristiques au niveau des groupes. Cette combinaison vous fournit un sous-ensemble propre et riche en caractéristiques, prêt pour la modélisation ou la création de rapports.
# Step 1: keep only large departments
filtered = df2.groupby('dept').filter(lambda g: len(g) >= 2)
# Step 2: add group mean salary to the filtered result
filtered = filtered.copy()
filtered['dept_avg'] = filtered.groupby('dept')['salary'].transform('mean')
print(filtered)Utiliser transform() pour propager les valeurs vers l’avant au sein des groupes
transform() est également utile avec des fonctions non numériques. Un cas courant consiste à remplir les valeurs manquantes au sein d’un groupe en utilisant la propagation vers l’avant ou la médiane du groupe, ce qui est bien plus pertinent qu’un remplissage global. Transmettez une fonction lambda qui appelle fillna() sur la Series du groupe ; le résultat possède alors le même index que le DataFrame d’origine.
import numpy as np
df3 = pd.DataFrame({
'dept': ['Eng', 'Eng', 'HR', 'HR', 'Eng'],
'salary': [90000, np.nan, 60000, np.nan, 88000]
})
# Fill NaN with the group mean
df3['salary_filled'] = df3.groupby('dept')['salary'].transform(
lambda s: s.fillna(s.mean())
)
print(df3)Modèle pratique : position relative
Un cas d’utilisation professionnel particulièrement utile consiste à calculer la position de chaque ligne par rapport à son groupe. En combinant transform() avec des opérations arithmétiques, vous pouvez ajouter des colonnes telles que : salaire moins la moyenne du groupe (écart), salaire exprimé comme fraction du total du groupe ou indicateur booléen précisant si cet employé gagne plus que la médiane du groupe. Ces caractéristiques sont extrêmement utiles pour les tableaux de bord et les modèles d’apprentissage automatique.
df['dept_total'] = df.groupby('dept')['salary'].transform('sum')
df['pct_of_total'] = (df['salary'] / df['dept_total'] * 100).round(1)
df['above_avg'] = df['salary'] > df.groupby('dept')['salary'].transform('mean')
print(df[['dept', 'salary', 'pct_of_total', 'above_avg']])Considérations relatives aux performances
transform() et filter(), lorsqu’ils utilisent des fonctions intégrées sous forme de chaînes, sont rapides, car ils empruntent des chemins d’exécution optimisés. En revanche, lorsque vous transmettez une fonction lambda ou une fonction Python personnalisée, Pandas doit appeler cette fonction une fois par groupe, ce qui peut être lent lorsque les données contiennent de nombreux groupes. Pour obtenir les meilleures performances avec de grands jeux de données, vérifiez si votre logique personnalisée peut être exprimée à l’aide d’une fonction intégrée sous forme de chaîne.
# Slower: custom lambda (called once per group)
df['dept_mean_slow'] = df.groupby('dept')['salary'].transform(lambda s: s.mean())
# Faster: built-in string shortcut (vectorised C path)
df['dept_mean_fast'] = df.groupby('dept')['salary'].transform('mean')
# Both give identical results, but the built-in is significantly fasterVérification rapide
Vérifiez votre compréhension de transform() et filter() avec GroupBy dans cette leçon.
Récapitulatif de la leçon
Dans cette leçon, vous avez appris que transform() renvoie des statistiques de groupe répercutées sur le nombre de lignes d’origine, ce qui en fait une méthode idéale pour ajouter des caractéristiques au niveau des groupes ; que filter() conserve ou supprime des groupes entiers en fonction d’une condition booléenne ; et que leur combinaison permet de créer des jeux de données riches et filtrés pour les analyses ultérieures. Nous allons maintenant découvrir comment combiner des DataFrames avec pd.concat.
Questions Fréquemment Posées
La leçon « Transformation et filtrage avec GroupBy » est-elle gratuite ?
Oui — le texte complet de « Transformation et filtrage avec GroupBy » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Pandas & NumPy Academy, passe à CoddyKit PRO. Le cours Pandas & NumPy Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Transformation et filtrage avec GroupBy » ?
Utilisez transform() pour ajouter des statistiques de groupe comme colonne et filter() pour ne conserver que les groupes satisfaisant une condition. Tu pratiques Pandas & NumPy Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Pandas & NumPy Academy ?
Aucune expérience préalable n'est requise. Pandas & NumPy Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Transformation et filtrage avec GroupBy » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Pandas & NumPy Academy ?
Oui. Chaque leçon Pandas & NumPy Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Le schéma diviser-appliquer-combiner
- GroupBy avec une ou plusieurs clés
- La méthode agg()
- Transformation et filtrage avec GroupBy