- Apprendre
- Informatique et numérique
- Science des données et IA
- Python et pandas : NumPy, analyse et visualisation de données
- Regroupement et agrégation avec pandas
Regroupement et agrégation avec pandas
IntermédiaireUnité 5 sur 8 de la formation Formation : Python et pandas : NumPy, analyse et visualisation de données
Ce que tu vas apprendre
- Expliquer le principe séparer-appliquer-combiner, créer des objets GroupBy à partir de différents types de clés et maîtriser les étiquettes, l’ordre et les éléments présents dans le résultat regroupé.
- Expliquer le principe séparer-appliquer-combiner et l’objet GroupByDécrire ce qui se passe lorsque pandas regroupe un DataFrame, examiner les groupes formés et sélectionner les colonnes à agréger.
- Regrouper à l’aide de colonnes, de tableaux, de correspondances, de fonctions et de niveaux d’indexChoisir et combiner des clés de regroupement : une ou plusieurs colonnes, des clés calculées, des correspondances, des fonctions ou des niveaux d’index.
- Maîtriser les clés de groupe, l’ordre et le traitement des clés manquantes dans les résultatsOrganiser les résultats regroupés pour la suite du travail : clés comme index ou colonnes, tri des résultats, clés manquantes et catégories inutilisées, et noms explicites.
- Expliquer le principe séparer-appliquer-combiner et l’objet GroupBy
- Réduire chaque groupe à des indicateurs à l’aide d’agrégations intégrées, de plusieurs agrégations en un seul appel et de fonctions personnalisées, puis interpréter correctement les résultats.
- Utiliser correctement les méthodes d’agrégation intégréesCalculer par groupe des effectifs, des totaux, des indicateurs de tendance centrale et de dispersion et d’autres indicateurs, et connaître leur traitement des valeurs manquantes et des colonnes textuelles.
- Appliquer plusieurs agrégations à la fois avec aggUtiliser agg avec des listes, des dictionnaires et l’agrégation nommée pour construire des tableaux de synthèse aux noms de colonnes explicites.
- Écrire des fonctions d’agrégation personnaliséesÉcrire tes propres fonctions qui réduisent un groupe à une valeur, nommer leurs résultats et savoir quand une fonction intégrée ou un rapport de sommes est préférable.
- Utiliser correctement les méthodes d’agrégation intégrées
- Ajouter les résultats des groupes à chaque ligne, calculer des valeurs cumulées et relatives au sein des groupes, conserver ou échantillonner des groupes et des lignes, et utiliser apply pour les opérations que les autres méthodes ne peuvent pas exprimer.
- Ajouter les statistiques du groupe à chaque ligne avec transformUtiliser transform pour diffuser les résultats des groupes sur les lignes d’origine afin de calculer des proportions, des écarts et des valeurs standardisées, et de remplacer les données manquantes selon le groupe.
- Calculer des sommes cumulées, des rangs et des variations au sein des groupesUtiliser des méthodes de cumul, de classement et de décalage qui repartent à zéro dans chaque groupe, et conserver les lignes dans l’ordre voulu.
- Conserver, supprimer ou échantillonner des lignes groupe par groupeFiltrer des groupes entiers selon une condition, prendre les premières, les dernières ou les meilleures lignes de chaque groupe et tirer des échantillons aléatoires au sein des groupes.
- Effectuer des opérations générales par groupe avec applyUtiliser apply pour les opérations par groupe qui nécessitent plusieurs colonnes ou renvoient des tables, prévoir la forme de son résultat et privilégier des méthodes plus rapides lorsqu’elles conviennent.
- Ajouter les statistiques du groupe à chaque ligne avec transform
- Transformer les valeurs quantitatives en catégories d’intervalles avec cut et qcut, calculer des quantiles et utiliser les classes comme clés de regroupement pour les analyses par classes et par quantiles.
- Répartir les valeurs en classes avec cutUtiliser cut avec des bornes explicites ou un nombre de classes de même amplitude, lire la notation des intervalles et maîtriser les bornes, les étiquettes et les valeurs hors des classes.
- Créer des classes de même effectif avec les quantiles et qcutCalculer des quantiles, créer des classes fondées sur les quantiles avec qcut, les comparer aux classes de même amplitude et traiter les ex æquo.
- Comparer des groupes définis par des classes et des quantilesUtiliser les résultats de cut et qcut comme clés de regroupement pour les analyses par classes et par quantiles, conserver les classes vides au besoin et interpréter les résultats avec prudence.
- Répartir les valeurs en classes avec cut
- Construire des tableaux de synthèse à double entrée avec pivot_table et crosstab, ajouter des totaux, convertir les effectifs en proportions et choisir le tableau qui répond à la question.
- Construire des tableaux croisés dynamiques avec pivot_tableSynthétiser des valeurs selon des clés de lignes et de colonnes avec pivot_table, choisir la fonction d’agrégation et ajouter des valeurs de remplacement et des totaux.
- Compter et comparer les catégories avec crosstabConstruire des tableaux des effectifs de deux variables qualitatives avec crosstab, ajouter des totaux, convertir les effectifs en proportions en ligne, en colonne ou globales, et choisir la proportion qui répond à la question.
- Construire des tableaux croisés dynamiques avec pivot_table
Regroupement et agrégation avec pandas : cours
1Répartir les données en groupes avec groupby
L’analyse par groupe commence par une question comme « Combien d’unités chaque région a-t-elle vendues ? ». Tu choisis les clés qui définissent un groupe, sélectionnes les valeurs à analyser et décides de la forme que doit prendre la réponse. Les mêmes lignes permettent de calculer des totaux régionaux, de comparer les produits ou de combiner les deux. Comprendre les clés, les index et les catégories manquantes facilite l’examen des résultats et leur utilisation dans un rapport.
1.1 Expliquer le principe séparer-appliquer-combiner et l’objet GroupBy
Un groupe contient les lignes qui ont la même valeur de clé. Si la clé est region, toutes les commandes North appartiennent au même groupe, même lorsqu’elles sont dispersées dans la table. Le principe séparer-appliquer-combiner consiste à repérer ces groupes, à effectuer la même opération dans chacun, puis à assembler les résultats.
Commencer par les données de commandes
Les exemples utilisent pandas 3 avec import pandas as pd et NumPy sous le nom np. Crée la table des commandes de boissons :
sales = pd.DataFrame({
"region": ["North", "South", "North", "East", "South", "East", "North", "South"],
"product": ["tea", "tea", "coffee", "coffee", "coffee", "tea", "tea", "coffee"],
"units": [10, 4, 7, 5, 9, 3, 6, 8],
"revenue": [30, 12, 28, 20, 36, 9, 18, 32]
})
Les recettes n’ont pas d’unité monétaire ici. Les recettes par unité sont de 3 pour le thé et de 4 pour le café. Les étiquettes de lignes par défaut vont de 0 à 7.
De l’objet GroupBy à la réponse
sales.groupby("region") renvoie un objet GroupBy, qui contient les informations de regroupement. Ce n’est pas une table de synthèse. Choisis une colonne et appelle une méthode pour calculer un résultat :
g = sales.groupby("region")
totals = g["units"].sum()
East contient les lignes 3 et 5, donc son total est 5 + 3 = 8. North contient les lignes 0, 2 et 6, ce qui donne 10 + 7 + 6 = 23. South contient les lignes 1, 4 et 7, ce qui donne 4 + 9 + 8 = 21. pandas combine ces résultats dans un objet Series nommé units, dont l’index contient les noms des régions. La somme des totaux est 52, le total de la colonne d’origine.
Par défaut, le résultat suit l’ordre East, North, South, car les clés de groupe sont triées. sales.groupby("region", sort=False) utilise l’ordre de première apparition : North, South, East. Aucun de ces choix ne trie les observations au sein d’un groupe ni ne modifie sales.
Examiner et sélectionner
g.ngroups vaut 3. g.size() indique 2, 3 et 3 lignes pour East, North et South. g.groups associe les clés aux étiquettes de lignes et g.get_group("North") renvoie les trois lignes North. Tu peux examiner un groupe à la fois :
for name, group in g:
print(name, group["units"].tolist())
L’itération aide à examiner ou à exporter les groupes. Pour calculer une statistique, une méthode de groupe intégrée évite d’écrire une boucle Python et de recueillir toi-même les résultats.
Sélectionner g["units"] produit un SeriesGroupBy dont la somme est un objet Series. Sélectionner g[["units"]] produit un DataFrameGroupBy dont la somme est un DataFrame à une colonne. Sélectionne g[["units", "revenue"]] lorsque les deux colonnes de nombres sont nécessaires.
Choisir la forme du résultat
Une agrégation comme sum donne un indicateur par groupe et par colonne. Une transformation donne une valeur pour chaque ligne d’entrée, par exemple la part de chaque commande dans le total de sa région. Un filtrage conserve les lignes ou les groupes sélectionnés. La méthode générale apply traite les résultats par groupe moins réguliers.
Le filtrage sales[sales["region"] == "North"] extrait les lignes d’une région. Le regroupement permet de traiter toutes les régions avec la même opération.
Points clés
- Les clés de regroupement déterminent quelles lignes vont ensemble.
- Un objet GroupBy a besoin d’une opération pour produire un résultat.
- Choisis une agrégation, une transformation ou un filtrage selon le résultat attendu.
- Le regroupement préserve la table d’origine et l’ordre des lignes au sein de chaque groupe.
1.2 Regrouper à l’aide de colonnes, de tableaux, de correspondances, de fonctions et de niveaux d’index
Les clés peuvent provenir de colonnes, de calculs ou de l’index des lignes. La question importante est de savoir quelle valeur chaque ligne reçoit comme clé. Les lignes qui partagent la même combinaison de clés sont traitées ensemble.
Utiliser plusieurs colonnes
Passe une liste de noms de colonnes pour regrouper selon leurs combinaisons :
pair_totals = sales.groupby(["region", "product"])["units"].sum()
Le résultat possède un MultiIndex à deux niveaux. Ses entrées sont East-coffee 5, East-tea 3, North-coffee 7, North-tea 16, South-coffee 17 et South-tea 4. North-tea combine les deux commandes de thé, de 10 et 6 unités. Un regroupement par région seule inclurait aussi la commande de café de North.
pair_totals.unstack() déplace le niveau interne product vers les colonnes. Les lignes représentent les régions et les colonnes représentent coffee et tea. Une combinaison absente devient NaN ; unstack(fill_value=0) peut la représenter par zéro lorsque cette absence signifie qu’il n’y a aucune unité.
Utilise une liste pour plusieurs noms de colonnes. groupby(("region", "product")) traite le tuple comme une seule étiquette de colonne et cherche une colonne portant ce tuple comme nom.
Calculer une clé à partir de valeurs
Un objet Series booléen peut répartir les commandes selon leur taille sans ajouter de colonne :
sales.groupby(sales["units"] >= 7)["revenue"].sum()
Le groupe True contient les unités 10, 7, 9 et 8 ; ses recettes sont de 126. Le groupe False contient les quatre autres commandes et ses recettes sont de 59. Le test crée des étiquettes de groupe ; il ne supprime pas les commandes plus petites.
Une correspondance peut réunir les régions en zones :
zones = {"North": "Zone 1", "East": "Zone 1", "South": "Zone 2"}
zone_key = sales["region"].map(zones)
sales.groupby(zone_key)["units"].sum()
Zone 1 reçoit les 23 unités de North et les 8 de East, soit un total de 31. Zone 2 reçoit les 21 de South. Établis d’abord la correspondance sur la colonne : un dictionnaire passé directement à groupby s’applique aux étiquettes d’index, et non aux valeurs de région.
Regrouper à l’aide de l’index
Une fonction passée comme clé reçoit elle aussi les étiquettes d’index. Pour un stock indexé par codes de produits, la première lettre peut désigner la famille de produits :
stock = pd.Series([12, 8, 5, 9, 4],
index=["T01", "T02", "C01", "C02", "C03"])
stock.groupby(lambda code: code[0]).sum()
Le total de C est 18 et celui de T est 20. Pour un MultiIndex existant, pair_totals.groupby(level="product").sum() regroupe à nouveau selon le niveau d’index nommé et produit coffee 29 et tea 23.
Vérifier l’alignement avant le regroupement
Un tableau NumPy utilisé comme clé fournit les étiquettes par position et doit comporter un élément par ligne. Un objet Series utilisé comme clé est aligné selon les étiquettes d’index. Si ses étiquettes ne couvrent que les lignes 0 et 1, les autres lignes reçoivent des clés manquantes et sont exclues par le comportement de regroupement par défaut. Un objet Series réordonné peut toujours regrouper correctement les lignes si ses étiquettes correspondent ; le remplacer par ses valeurs transforme l’opération en une association par position.
Points clés
- Utilise une liste de noms de colonnes pour regrouper selon leurs combinaisons.
- Un objet Series utilisé comme clé s’aligne selon les étiquettes d’index ; un tableau fournit les valeurs par position.
- Établis la correspondance sur les valeurs d’une colonne avant le regroupement lorsqu’un dictionnaire décrit ces valeurs.
- Les fonctions passées comme clés reçoivent les étiquettes d’index.
- Utilise
levelpour les niveaux d’index etunstackpour déplacer un niveau d’index vers les colonnes. - Une clé booléenne répartit les lignes en groupes selon une condition sans supprimer aucun des groupes.
1.3 Maîtriser les clés de groupe, l’ordre et le traitement des clés manquantes dans les résultats
Un calcul par groupe comporte deux éléments à examiner : les valeurs et les étiquettes qui les entourent. pandas te permet de choisir où apparaissent les clés, comment les groupes sont ordonnés et si les clés manquantes ou inutilisées figurent dans le rapport.
Conserver les clés dans l’index ou dans des colonnes
Par défaut, les clés deviennent l’index du résultat :
sales.groupby("region")["revenue"].sum()
Cet objet Series contient East 29, North 76 et South 80. Pour obtenir un rapport sans index hiérarchique, utilise :
report = sales.groupby("region", as_index=False)["revenue"].sum()
report possède des colonnes ordinaires region et revenue et un nouvel index entier. Appeler .reset_index() sur l’objet Series d’origine produit la même disposition. Avec plusieurs clés, cette méthode convertit chaque niveau du MultiIndex en colonne. unstack() a un autre rôle : il déplace un niveau d’index vers les colonnes d’une grille.
Un résultat de type Series conserve le nom de la colonne sélectionnée. Utilise .rename("total_revenue") pour donner un nom plus explicite à l’objet Series ou .to_frame("total_revenue") pour obtenir un DataFrame à une colonne. L’agrégation nommée peut fournir des noms de colonnes descriptifs pendant le calcul.
Trier les clés ou classer les valeurs
sort=True trie les clés : l’ordre alphabétique des régions reste donc East, North, South même si South a les recettes les plus élevées. Pour classer les totaux, trie le résultat :
sales.groupby("region")["revenue"].sum().sort_values(ascending=False)
Le résultat est South 80, North 76, East 29. Utilise sort=False pour conserver l’ordre de première apparition des clés et éviter un tri inutile des clés sur un jeu de données volumineux. Ce réglage ne trie pas les lignes au sein des groupes.
Tenir compte des clés manquantes
Le réglage par défaut dropna=True exclut les lignes dont la clé de groupe est manquante. Ajoute une commande de 5 unités sans région : le total de la colonne entière des unités est maintenant de 57, tandis que la somme des totaux par groupe reste égale à 52. La ligne omise n’a pas de région nommée.
sales.groupby("region", dropna=False)["units"].sum()
Sur la table ainsi agrandie, cette commande ajoute un groupe de clés manquantes dont le total est 5. Les clés manquantes déterminent si une ligne entre dans un groupe ; les valeurs manquantes déterminent ce qu’une agrégation compte ou calcule au sein d’un groupe. Ce sont deux décisions distinctes.
Afficher les catégories inutilisées au besoin
Une colonne catégorielle region peut contenir les catégories East, North, South et West même en l’absence de commandes West. Depuis pandas 3.0, observed=True est le réglage par défaut et n’affiche que les catégories présentes dans les données. Avec observed=False, West apparaît aussi : sa somme et son effectif sont 0, tandis que sa moyenne est NaN.
Choisis explicitement ce réglage lorsqu’un rapport doit présenter les mêmes catégories à chaque fois. Une catégorie inutilisée et une clé manquante sont deux choses différentes : observed gère les valeurs catégorielles déclarées ; dropna gère les valeurs de clés absentes.
as_index et sort déterminent la forme des résultats d’agrégation. Les transformations et les filtrages comme head, nth et filter conservent les index des lignes d’entrée. Pour un rapport de sommes, comparer la somme des totaux de groupe au total de la colonne d’origine peut révéler des clés exclues ou un filtre appliqué auparavant.
Points clés
as_index=Falseplace les clés d’agrégation dans des colonnes ordinaires.sortordonne les clés ;sort_valuesclasse les valeurs calculées.dropna=Falseconserve un groupe pour les clés manquantes.observed=Falseinclut les valeurs catégorielles inutilisées.
2Calculer des indicateurs pour chaque groupe par agrégation
Un tableau de synthèse transforme de nombreuses observations en quelques mesures utiles. Les effectifs, les totaux, les indicateurs de tendance centrale et les mesures de dispersion répondent à des questions différentes, même lorsqu’ils utilisent les mêmes groupes. Tu choisiras des fonctions intégrées adaptées, réuniras plusieurs résultats en un seul appel et écriras une fonction personnalisée au besoin. Les valeurs manquantes et les différences d’effectifs comptent : un tableau bien présenté peut tout de même répondre à la mauvaise question.
2.1 Utiliser correctement les méthodes d’agrégation intégrées
Une agrégation réduit chaque groupe à un indicateur pour chaque colonne sélectionnée. Choisis la mesure en fonction de la question : un nombre de lignes, un total, un indicateur de tendance centrale ou une mesure de dispersion décrit une caractéristique différente des données.
Sélectionner la statistique
Les méthodes courantes comprennent sum, prod, mean, median, min, max, count, size, nunique, std, var, first, last et quantile. Un appel direct comme .mean() et .agg("mean") demandent tous deux une moyenne par groupe calculée par pandas. Par défaut, nunique() compte les valeurs distinctes non manquantes.
sales.groupby("product")["revenue"].agg(["mean", "median"])
Les recettes du café sont 28, 20, 36 et 32. Leur moyenne est 29 ; une fois triées, les valeurs centrales sont 28 et 32, donc leur médiane est 30. Les recettes du thé sont 30, 12, 9 et 18. Leur moyenne est 17,25 et leur médiane 15. La commande de thé élevée de 30 tire la moyenne au-dessus de la médiane.
Compter les lignes ou les valeurs enregistrées
size() compte les lignes. count() compte les valeurs non manquantes dans chaque colonne sélectionnée. Si les unités sont manquantes pour la ligne 2 de North et la ligne 5 de East, les nombres de lignes restent East 2, North 3, South 3, mais les nombres de valeurs d’unités sont 1, 2 et 3. Différentes colonnes peuvent donc avoir des nombres de valeurs différents au sein d’un même groupe.
La plupart des réductions quantitatives ignorent les valeurs manquantes. Les unités restantes de North, 10 et 6, ont une moyenne de 8, calculée à partir de deux valeurs enregistrées. Diviser leur somme par les trois lignes donnerait une moyenne erronée. Un groupe dont toutes les valeurs sont manquantes a par défaut une somme de 0, mais une moyenne NaN. Depuis pandas 3.0, les réductions comme sum et mean acceptent skipna=False pour renvoyer un résultat manquant lorsqu’un groupe contient une valeur manquante.
Interpréter la dispersion et les indicateurs combinés
std() et var() utilisent des statistiques d’échantillon, avec ddof=1 : le diviseur est le nombre d’observations enregistrées moins un. Les valeurs 1 et 3 ont un écart-type d’échantillon d’environ 1,414. Un groupe contenant seulement la valeur 5 a un écart-type d’échantillon NaN.
describe() réunit l’effectif, la moyenne, l’écart-type, le minimum, les quartiles et le maximum. Pour les recettes de South, 12, 36 et 32, la moyenne est d’environ 26,67 et la médiane est 32. La colonne 50 % donne la médiane.
Maîtriser les colonnes et l’ordre des lignes
Sélectionner les colonnes de nombres évite d’essayer de calculer la moyenne de texte :
sales.groupby("region")[["units", "revenue"]].mean()
Un appel de .mean() sur toute la table échoue à cause de la colonne textuelle product ; numeric_only=True est une autre solution. Un appel de .sum() sur toute la table peut concaténer le texte et produire "coffeetea" pour East, ce qui ne constitue pas un indicateur utile des produits.
first() et last() choisissent la première et la dernière valeur non manquante de chaque colonne dans l’ordre actuel des lignes. Ces valeurs peuvent provenir de lignes différentes. Utilise nth(0) pour extraire la première ligne effective, y compris ses valeurs manquantes ; trie d’abord lorsque « première » signifie la plus ancienne.
Les différences d’effectifs entre groupes influent aussi sur l’interprétation. La moyenne des recettes moyennes régionales est d’environ 22,17, mais la moyenne globale est de 185 divisé par 8, soit 23,125. Donner le même poids à chaque moyenne régionale donne au groupe East de deux lignes autant d’influence qu’à chacun des groupes de trois lignes.
Points clés
sizecompte les lignes ;countcompte les valeurs enregistrées.- La plupart des réductions ignorent les valeurs manquantes ; la somme de valeurs toutes manquantes vaut zéro par défaut.
stdetvarutilisent par défaut le diviseur d’échantillon.- Sélectionne les colonnes de nombres pertinentes avant l’agrégation.
firstpeut ignorer les valeurs manquantes ;nth(0)sélectionne une ligne effective.- Des groupes d’effectifs différents nécessitent des poids adaptés pour combiner leurs moyennes.
2.2 Appliquer plusieurs agrégations à la fois avec agg
Un rapport utile nécessite souvent plusieurs mesures pour les mêmes groupes. agg, forme abrégée de aggregate, permet de demander ces mesures ensemble et de maîtriser le nom des colonnes de résultat.
Appliquer plusieurs fonctions à une colonne
sales.groupby("region")["revenue"].agg(["sum", "mean", "max"])
East donne 29, 14,5 et 20 ; North donne 76, environ 25,33 et 30 ; South donne 80, environ 26,67 et 36. Chaque ligne représente une région, tandis que les noms de fonctions deviennent des noms de colonnes.
Une liste appliquée à plusieurs colonnes de valeurs produit des colonnes hiérarchiques :
result = sales.groupby("region")[["units", "revenue"]].agg(["sum", "mean"])
Les quatre étiquettes de colonnes sont les paires ("units", "sum"), ("units", "mean"), ("revenue", "sum") et ("revenue", "mean"). Le premier niveau désigne la colonne d’entrée ; le second désigne le calcul. Ce sont des niveaux de colonnes, distincts des éventuels niveaux de regroupement dans l’index des lignes.
Attribuer des fonctions à des colonnes précises
Un dictionnaire sélectionne les colonnes d’entrée et leurs fonctions :
sales.groupby("region").agg({
"units": "sum",
"revenue": ["mean", "max"]
})
Cette commande demande le total des unités, mais la moyenne et le maximum des recettes. Les colonnes absentes du dictionnaire n’apparaissent pas. Des fonctions différentes peuvent convenir à des mesures différentes ; additionner une quantité et calculer la moyenne d’un taux ne sont pas des choix interchangeables.
Nommer directement les résultats
L’agrégation nommée donne un nom explicite à chaque résultat :
report = sales.groupby("region").agg(
total_units=("units", "sum"),
avg_revenue=("revenue", "mean")
)
Chaque mot-clé nomme une colonne de résultat. Son tuple contient la colonne source et la fonction. total_units vaut 8, 23 et 21 ; avg_revenue vaut 14,5, environ 25,33 et environ 26,67. pd.NamedAgg(column="units", aggfunc="sum") est une fonction utilitaire équivalente pour préciser la source et la fonction.
Après avoir sélectionné un seul objet Series, utilise des mots-clés de fonctions sans tuples de colonnes sources :
sales.groupby("region")["units"].agg(total="sum", most="max")
Les totaux sont 8, 23 et 21, et les maximums 5, 10 et 9. Un dictionnaire tel que {"total": "sum"} appliqué à cet objet Series sélectionné déclenche une SpecificationError ; ce n’est pas la forme de dictionnaire utilisée sur un DataFrame.
Une liste de paires nommées fonctionne aussi sur une colonne sélectionnée : .agg([("average", "mean"), ("spread", "std")]). Si tu disposes déjà de colonnes à MultiIndex créées à partir d’étiquettes textuelles, result.columns = ["_".join(col) for col in result.columns] les aplatit et produit des noms comme units_sum.
Choisir la fonction avec soin
Les noms sous forme de chaînes utilisent les calculs par groupe intégrés à pandas. Depuis pandas 3.0, une fonction NumPy ou Python passée à agg est appelée telle qu’elle est fournie. Pour les recettes de East, 20 et 9, "std" utilise le diviseur d’échantillon et donne environ 7,78, tandis que np.std utilise le diviseur de population et donne 5,5.
Points clés
- Une liste applique plusieurs fonctions aux colonnes sélectionnées.
- Un dictionnaire attribue des fonctions à des colonnes d’entrée précises.
- L’agrégation nommée utilise des noms de résultats associés à des paires
(column, function). - Les noms de fonctions sous forme de chaînes et les objets appelables NumPy peuvent utiliser des paramètres statistiques par défaut différents.
2.3 Écrire des fonctions d’agrégation personnalisées
Une agrégation personnalisée permet de calculer un indicateur qu’un nom de fonction intégrée ne fournit pas. Sa fonction reçoit les valeurs d’un groupe sous forme d’objet Series et doit les réduire à un résultat utile.
Écrire et passer la fonction
def value_range(s):
return s.max() - s.min()
sales.groupby("region")["revenue"].agg(value_range)
L’étendue de East est 20 moins 9, soit 11. Celle de North est 30 moins 18, soit 12. Celle de South est 36 moins 12, soit 24. Passe value_range lui-même ; value_range() l’appellerait immédiatement sans l’objet Series du groupe dont il a besoin.
Une expression lambda convient à un calcul court :
sales.groupby("region")["revenue"].agg(
share_20=lambda s: (s >= 20).mean()
)
Les valeurs booléennes se comportent comme 1 pour True et 0 pour False : leur moyenne est donc la proportion de valeurs qui satisfont la condition. East compte une commande admissible sur deux, soit 0,5. North et South en comptent chacune deux sur trois, soit environ 0,667. Nommer le résultat rend son sens plus clair qu’une étiquette automatique d’expression lambda. Dans les listes contenant plusieurs fonctions, les expressions lambda sont nommées <lambda_0>, <lambda_1>, etc. ; une expression lambda seule dans une liste est nommée <lambda>.
Préparer des colonnes pour utiliser des réductions rapides
Une fonction Python s’exécute une fois pour chaque groupe. Lorsqu’il y a beaucoup de groupes, les réductions intégrées sont généralement plus rapides. Le calcul de la proportion peut être réécrit en créant d’abord sa colonne booléenne :
sales.assign(big=sales["revenue"] >= 20).groupby("region")["big"].mean()
La comparaison s’effectue sur toute la colonne, puis pandas calcule les moyennes des groupes.
Combiner deux colonnes à l’aide de leurs totaux
Une fonction agg traite une colonne à la fois. Pour obtenir les recettes moyennes par unité, calcule d’abord un indicateur pour chacune des deux colonnes :
totals = sales.groupby("region")[["units", "revenue"]].sum()
avg_price = totals["revenue"] / totals["units"]
Les résultats sont East 29/8 = 3,625, North 76/23 ≈ 3,304 et South 80/21 ≈ 3,810. Chaque unité reçoit le même poids. Calculer à la place la moyenne des prix des commandes donne East 3,5, North environ 3,333 et South environ 3,667, car chaque commande reçoit le même poids quelle que soit sa taille. Détermine si la question porte sur une unité typique ou sur une commande typique avant de choisir la formule.
Préciser la valeur renvoyée et le traitement des données manquantes
Une fonction qui renvoie les deux plus petites valeurs ne crée pas deux lignes d’indicateurs ordinaires avec agg ; dans pandas 3.1, lambda s: s.nsmallest(2) stocke un objet de type liste dans chaque cellule. Utilise apply lorsqu’un groupe doit renvoyer plusieurs valeurs ou lignes.
L’objet Series d’entrée contient toujours les valeurs manquantes. s.mean() les ignore, tandis que len(s) compte leurs lignes. Si les unités des lignes 2 et 5 sont manquantes, .agg(len) donne les nombres de lignes des groupes, 2, 3 et 3, et non les nombres de valeurs non manquantes, 1, 2 et 3.
Des arguments supplémentaires peuvent suivre la fonction : .agg("quantile", 0.9) donne le 90e centile de chaque groupe. Les recettes de East, 9 et 20, donnent 18,9 par interpolation linéaire. L’appel direct .quantile(0.9) est plus facile à lire pour cette seule opération.
Points clés
- Passe une fonction à
aggsans l’appeler au préalable. - Une agrégation personnalisée reçoit l’objet Series d’un groupe et doit renvoyer un indicateur.
- Les moyennes de valeurs booléennes donnent des proportions.
- Un rapport de totaux pondère les unités différemment d’une moyenne de rapports calculés par ligne.
- Privilégie les réductions intégrées lorsqu’elles permettent d’exprimer le calcul.
- Les fonctions personnalisées doivent traiter les valeurs manquantes de manière réfléchie.
3Transformer, filtrer et appliquer des fonctions groupe par groupe
Un groupe peut fournir un contexte pour chaque ligne d’origine, et pas seulement un indicateur distinct. Une commande peut recevoir le total de sa région, son rang ou la variation par rapport à la commande précédente de cette région. D’autres opérations conservent les groupes sélectionnés ou renvoient une table pour chaque groupe. Choisir une méthode selon la forme de son résultat clarifie le travail et évite les erreurs d’alignement des index lors de l’ajout d’un résultat aux données d’origine.
3.1 Ajouter les statistiques du groupe à chaque ligne avec transform
Un tableau de synthèse comporte une ligne par groupe, mais chaque ligne d’origine a parfois besoin de la statistique de son groupe. transform renvoie un résultat de même longueur et de même index que les données d’origine, ce qui permet de l’utiliser pour une nouvelle colonne.
Diffuser un total sur les bonnes lignes
g = sales.groupby("region")["revenue"]
regional_total = g.transform("sum")
sales["share"] = sales["revenue"] / regional_total
L’objet Series des totaux contient 76, 80, 76, 29, 80, 29, 76 et 80 dans l’ordre des lignes d’origine. Le total de North, 76, est répété uniquement sur les lignes North. La ligne 0 reçoit une proportion de 30/76 ≈ 0,395 ; la ligne 3 de East reçoit 20/29 ≈ 0,690. Dans chaque région, la somme de ces parts de recettes vaut 1.
Affecter directement g.sum() ne permettrait pas de faire correspondre les lignes. Son index contient les noms des régions, tandis que sales possède les étiquettes de lignes 0 à 7. pandas aligne les données selon les étiquettes d’index : la colonne affectée ne contient donc que des valeurs manquantes. Utilise transform ou fusionne explicitement un tableau de synthèse sur region.
Comparer une ligne à son groupe
Soustraire la moyenne du groupe donne un écart à la moyenne du groupe :
x = sales["revenue"]
deviation = x - g.transform("mean")
La ligne 0 de North se situe environ 4,67 au-dessus de la moyenne de son groupe, qui est d’environ 25,33. La ligne 1 de South se situe environ 14,67 en dessous de la moyenne de son groupe, qui est d’environ 26,67. Chaque comparaison utilise la région propre à la ligne, et non la moyenne de toute la table.
Un score z divise cet écart par l’écart-type du groupe :
z = (x - g.transform("mean")) / g.transform("std")
Pour la ligne 0 de North, l’écart-type d’échantillon est d’environ 6,43 et le score z d’environ 0,73. La ligne 3 de East a un score z d’environ 0,71 : elle est donc au-dessus de la moyenne de sa région, même si sa recette de 20 est inférieure à la moyenne globale de 23,125. Un écart-type nul ou un nombre insuffisant de valeurs enregistrées laisse le score z indéfini.
Remplacer une valeur manquante à partir de son groupe
Supposons que les unités des lignes 2 et 5 soient manquantes. Les unités enregistrées de North sont 10 et 6, avec une moyenne de 8 ; la seule valeur d’unités enregistrée pour East est 5.
with_missing = sales.copy()
with_missing.loc[[2, 5], "units"] = np.nan
means = with_missing.groupby("region")["units"].transform("mean")
filled_units = with_missing["units"].fillna(means)
Sur cette table modifiée, la ligne 2 reçoit 8 et la ligne 5 reçoit 5. Les valeurs existantes restent inchangées. Lorsque les groupes ont des valeurs typiques différentes, leurs propres moyennes peuvent fournir des valeurs de remplacement plus réalistes qu’une seule moyenne globale. Un groupe sans valeur enregistrée n’a toujours pas de moyenne à fournir.
Comprendre une transformation personnalisée
Une fonction fournie à transform peut renvoyer un scalaire, que pandas répète dans le groupe, ou un objet Series indexé sur les lignes du groupe. Par exemple, g.transform(lambda s: s - s.mean()) calcule les mêmes écarts que la moyenne intégrée suivie d’une soustraction, mais fait appel à Python pour chaque groupe.
Un objet Series renvoyé plus court est associé aux lignes par étiquette. g.transform(lambda s: s.head(1)) ne fournit que la valeur de la première ligne de chaque groupe ; les autres lignes reçoivent NaN. Conserve l’index d’origine pour les calculs par ligne lorsque le résultat doit être affecté à nouveau à la table.
Points clés
transformrenvoie des résultats alignés sur les lignes d’entrée.- Divise chaque valeur par le total de son groupe obtenu avec transform pour calculer les proportions au sein du groupe.
- Utilise les moyennes et les écarts-types des groupes pour les comparaisons au sein des groupes.
- Le remplacement par groupe utilise la statistique du groupe auquel appartient la ligne contenant la valeur manquante.
3.2 Calculer des sommes cumulées, des rangs et des variations au sein des groupes
Les calculs cumulés et les comparaisons avec les observations précédentes nécessitent à la fois un groupe et un ordre des lignes. Le regroupement empêche un calcul de passer à un autre groupe ; le tri détermine ce que signifient « précédent » ou « jusqu’ici ».
Cumuler au sein de chaque groupe
Supposons que les lignes de commandes soient déjà classées dans l’ordre chronologique :
sales["running_units"] = sales.groupby("region")["units"].cumsum()
Les unités de North, 10, 7 et 6, produisent les sommes cumulées 10, 17 et 23. Celles de South, 4, 9 et 8, produisent 4, 13 et 21. Celles de East, 5 et 3, produisent 5 et 8. Ces valeurs restent associées à leurs étiquettes de lignes d’origine : le résultat complet dans l’ordre des lignes est donc 10, 4, 17, 5, 13, 8, 23 et 21.
Sans groupby, sales["units"].cumsum() donnerait un seul total cumulé pour toutes les commandes : 10, 14, 21, 26, 35, 38, 44 et 52. Le calcul par groupe repart de zéro pour chaque région. Les méthodes apparentées comprennent cumprod, cummax et cummin pour les produits, maximums et minimums cumulés.
cumcount() compte les positions au sein des groupes à partir de zéro. Ici, il donne 0, 0, 1, 0, 1, 1, 2 et 2. Ajoute 1 pour obtenir les numéros de première, deuxième et troisième commande dans chaque région.
Attribuer des rangs sans déplacer les lignes
sales.groupby("region")["revenue"].rank(ascending=False)
La recette la plus élevée reçoit le rang 1 dans sa région : ligne 0 de North, ligne 4 de South et ligne 3 de East. Le résultat conserve l’index d’entrée ; l’attribution des rangs ne déplace pas les lignes les plus élevées en haut de la table.
Par défaut, les valeurs ex æquo reçoivent leur rang moyen. Si deux valeurs sont ex æquo à la première place, elles reçoivent toutes deux 1,5 et la suivante reçoit 3. method="min" donne 1 aux valeurs ex æquo et toujours 3 à la suivante. method="dense" donne 1 aux valeurs ex æquo et 2 à la suivante. Choisis une règle de traitement des ex æquo adaptée à l’interprétation des rangs.
Comparer des valeurs consécutives
g = sales.groupby("region")["units"]
previous = g.shift(1)
change = g.diff()
relative_change = g.pct_change()
Pour North, les valeurs précédentes sont manquante, 10 et 7. Les différences sont manquante, −3 et −1. Les variations relatives sont manquante, −0,3 et environ −0,143 : la différence est divisée par la valeur précédente. pct_change() renvoie une proportion : −0,3 signifie donc une baisse de 30 %, et non de 0,3 %.
La première observation de chaque groupe n’a pas d’observation précédente et reçoit NaN. Un simple shift() sur la colonne utiliserait la ligne précédente de toute la table, qui pourrait appartenir à une autre région.
Avant ces calculs qui dépendent de l’ordre, trie les lignes selon la colonne qui définit la séquence, par exemple une date ou un numéro d’événement. groupby(sort=True) ne trie que les clés de groupe ; il ne peut pas mettre les observations dans l’ordre chronologique. L’attribution des rangs compare les valeurs et traite les ex æquo indépendamment de la chronologie, tandis que les calculs cumulés et décalés dépendent de la séquence choisie.
Points clés
- Trie les observations avant les calculs qui dépendent de leur ordre.
- Les méthodes cumulatives par groupe repartent de zéro dans chaque groupe.
cumcountcommence à zéro ; ajoute 1 pour obtenir les numéros usuels dans la séquence.- Choisis explicitement le sens du classement et la méthode de traitement des ex æquo au besoin.
shift,diffetpct_changecomparent les observations au sein d’un même groupe.pct_changerenvoie une proportion que l’on peut multiplier par 100 pour obtenir un pourcentage.
3.3 Conserver, supprimer ou échantillonner des lignes groupe par groupe
Conserver un groupe et calculer un indicateur sur ce groupe sont deux opérations différentes. Un filtre de groupes utilise une condition portant sur l’ensemble du groupe pour décider quelles lignes d’origine conserver ; les méthodes de sélection de lignes choisissent certaines observations dans chaque groupe.
Conserver des groupes entiers
sales.groupby("region").filter(lambda g: len(g) >= 3)
North et South ont chacune trois commandes, tandis que East en a deux. Le résultat contient les lignes 0, 1, 2, 4, 6 et 7, dans leur ordre et avec leurs étiquettes d’origine. Il ne renvoie pas deux lignes d’indicateurs régionaux.
La condition doit produire une valeur booléenne par groupe. lambda g: g["units"] > 5 produit un objet Series booléen et n’est pas valide pour filter. Réduis cette condition avec all() ou any() :
sales.groupby("region").filter(lambda g: (g["units"] > 5).all())
Seul North satisfait la condition, car toutes ses valeurs d’unités, 10, 7 et 6, dépassent 5. Utiliser any() conserve aussi South, car au moins une de ses commandes dépasse 5.
La taille du groupe obtenue avec une transformation fournit un masque aligné sur les lignes, plus rapide pour la première tâche :
sizes = sales.groupby("region")["units"].transform("size")
sales[sizes >= 3]
Ce masque peut être combiné à d’autres conditions sur les lignes avec & et |. Filtrer à la place sales.groupby("region")["revenue"].sum() conserverait des entrées d’indicateurs, et non les commandes d’origine.
Prendre des lignes par position
head(n) prend les n premières lignes de chaque groupe, tail(n) les n dernières et nth(k) la ligne de position k, en comptant à partir de zéro. sales.groupby("region").head(1) renvoie les lignes 0, 1 et 3 : la première commande observée de chaque région. La présence de valeurs manquantes ne conduit pas head(1) à chercher une ligne ultérieure non manquante.
Pour sélectionner la commande la plus élevée par région, trie d’abord selon les recettes :
sales.sort_values("revenue", ascending=False).groupby("region").head(1)
Les lignes sélectionnées sont la ligne 4 de South, avec une recette de 36, la ligne 0 de North, avec 30, et la ligne 3 de East, avec 20. Le tri détermine quelle observation est première ; l’opération par groupe prend ensuite cette première ligne. Avec des étiquettes de lignes uniques, sales.loc[sales.groupby("region")["revenue"].idxmax()] extrait les mêmes maximums à partir de leurs étiquettes.
Échantillonner au sein de chaque groupe
sales.groupby("region").sample(n=1, random_state=0)
Cette commande tire une commande de chaque région. Définir random_state rend reproductibles les exécutions répétées sur les mêmes données. Un échantillon tiré du DataFrame entier pourrait omettre une région, même si celle-ci contient trois lignes au total.
Utilise frac=0.5 pour tirer environ la moitié des lignes de chaque groupe. La taille de l’échantillon par groupe est arrondie : avec frac=0.2, les deux lignes de East donnent 0,4 ligne, arrondi à zéro. Utilise explicitement n=1 lorsque chaque groupe non vide doit fournir une observation. La taille d’échantillon demandée doit être réalisable pour les groupes avec les paramètres d’échantillonnage choisis.
Points clés
filterrenvoie les lignes d’origine des groupes qui satisfont une condition booléenne unique.head,tailetnthsélectionnent des lignes dans l’ordre actuel.- Trie avant
headlorsque tu sélectionnes les valeurs les plus élevées. - Un échantillonnage par groupe avec
n=1représente chaque groupe non vide ; une petite fraction peut omettre les petits groupes.
3.4 Effectuer des opérations générales par groupe avec apply
apply permet à une fonction d’examiner un groupe entier et de renvoyer un scalaire, un objet Series ou un DataFrame. Cette souplesse est utile lorsque des colonnes doivent interagir ou que le résultat contient plusieurs lignes. Elle rend aussi la forme du résultat moins prévisible qu’avec agg ou transform.
Utiliser plusieurs colonnes ensemble
def price_per_unit(g):
return g["revenue"].sum() / g["units"].sum()
sales.groupby("region").apply(price_per_unit)
La fonction reçoit les lignes d’une région. Elle renvoie une valeur : pandas combine donc les résultats dans un objet Series indexé par région, avec East 3,625, North environ 3,304 et South environ 3,810. Un rapport de sommes par groupe calculées par les méthodes intégrées produit le même résultat avec moins de travail pour Python. np.average(g["revenue"] / g["units"], weights=g["units"]) exprime la moyenne pondérée équivalente.
Pour une statistique faisant intervenir deux colonnes, comme la corrélation entre les heures d’étude et la note au sein de chaque groupe de cours, apply peut transmettre les deux objets Series de chaque groupe à .corr().
Prévoir la combinaison des résultats
Une fonction qui renvoie un objet Series avec les mêmes étiquettes pour chaque groupe crée une ligne de table par groupe :
sales.groupby("region").apply(
lambda g: pd.Series({
"orders": len(g),
"avg_price": g["revenue"].sum() / g["units"].sum()
})
)
Les colonnes sont orders et avg_price. Les effectifs apparaissent sous la forme 2.0, 3.0 et 3.0, car l’objet Series renvoyé contient aussi un prix à virgule flottante. Si les objets Series renvoyés utilisent des étiquettes différentes, pandas les empile dans un objet Series plus long, en ajoutant les clés de groupe comme niveau d’index externe.
Un DataFrame par groupe est empilé dans un DataFrame plus grand :
def top(g, n=2, col="revenue"):
return g.sort_values(col, ascending=False).head(n)
sales.groupby("region").apply(top)
Les lignes sont East 3 et 5, North 0 et 2, et South 4 et 7. Chaque groupe est trié indépendamment. Les arguments supplémentaires suivent la fonction : .apply(top, n=1, col="units") modifie la sélection pour obtenir la commande qui comporte le plus d’unités.
Maîtriser les clés et l’alignement
Pour ces lignes renvoyées, le réglage par défaut group_keys=True ajoute la région comme niveau d’index externe. sales.groupby("region", group_keys=False).apply(top) ne conserve que les étiquettes de lignes d’origine. Il assemble toujours les résultats groupe par groupe ; il ne garantit pas l’ordre des lignes de la table d’entrée.
Depuis pandas 3.0, le DataFrame transmis à un apply par groupe exclut les colonnes de regroupement. Dans cet exemple, il contient product, units et revenue, mais pas region. Lis la clé du groupe courant dans g.name lorsque la fonction en a besoin.
Utiliser la méthode la plus ciblée lorsqu’elle convient
apply exécute du code Python pour chaque groupe et détermine comment assembler le résultat. Utilise agg pour les indicateurs par colonne, transform pour les résultats alignés sur chaque ligne d’entrée et filter pour décider de conserver ou de supprimer des groupes entiers.
Par exemple, soustraire la moyenne de chaque région avec apply sur un objet Series sélectionné renvoie des différences sous un MultiIndex composé de la région et de la ligne. transform renvoie les différences avec l’index d’origine, prêtes à être affectées à une colonne.
Points clés
applypeut utiliser plusieurs colonnes et renvoyer des résultats de formes variées.- Un résultat scalaire donne un objet Series ; des objets Series aux étiquettes identiques donnent une table.
- Les résultats de type DataFrame sont empilés, généralement avec les clés de groupe dans l’index.
- Depuis pandas 3.0, un
applypar groupe exclut les colonnes de regroupement de chaque groupe transmis en entrée. - Privilégie
agg,transformoufilterlorsque leur type de résultat convient. - Utilise
group_keyspour maîtriser les étiquettes de groupe externes, et non pour rétablir l’ordre des lignes d’origine.
4Discrétiser les données quantitatives et analyser les groupes définis par des classes et des quantiles
Les valeurs quantitatives peuvent devenir des étiquettes de groupe utiles lorsque tu les répartis en intervalles. Des bornes fixes permettent de comparer les mêmes plages entre rapports ; les quantiles permettent de comparer les parties inférieure et supérieure d’un échantillon. Tu créeras ces deux types de classes, examineras les bornes et les ex æquo, puis calculeras un indicateur d’une autre variable dans chaque classe. Les effectifs indiqués à côté des indicateurs montrent la quantité de données sur laquelle repose chaque comparaison.
4.1 Répartir les valeurs en classes avec cut
La discrétisation remplace les valeurs quantitatives par des catégories d’intervalles. Utilise-la lorsqu’un rapport nécessite des plages qui ont un sens, comme des tranches de notes, plutôt qu’un groupe distinct pour chaque nombre.
Définir des bornes explicites
scores = pd.Series([42, 50, 55, 64, 68, 70, 73, 81, 85, 88, 97, 100])
bands = pd.cut(scores, [0, 50, 70, 85, 100])
bands.value_counts(sort=False)
Cinq bornes définissent quatre classes : (0, 50], (50, 70], (70, 85] et (85, 100]. Elles contiennent 2, 4, 3 et 3 notes. Les bornes explicites peuvent définir des classes d’amplitudes différentes, car elles représentent des seuils qui ont un sens.
Dans la notation affichée par pandas, une parenthèse exclut une borne et un crochet l’inclut. Avec le réglage par défaut right=True, 50 appartient à la première classe, 70 à la deuxième, 85 à la troisième et 100 à la quatrième. Lis (50, 70] comme « strictement supérieur à 50 et inférieur ou égal à 70 ».
Traiter les bornes extrêmes
Avec ces bornes explicites, 0 est exclu du premier intervalle et 101 se trouve au-delà du dernier intervalle. Les deux reçoivent NaN. Utilise include_lowest=True pour inclure une valeur égale à la borne la plus basse. Les valeurs inférieures à la borne la plus basse ou supérieures à la borne la plus haute ne reçoivent toujours pas de classe.
Pour des intervalles fermés à gauche, utilise right=False. Les mêmes bornes définissent alors [0, 50), [50, 70), [70, 85) et [85, 100). Maintenant, 50 passe dans la deuxième classe et 100 est exclu. Les effectifs de l’exemple deviennent 1, 4, 3 et 3, avec une affectation de classe manquante. Une borne supérieure de 101 inclurait la note 100 dans la dernière classe fermée à gauche.
Modifier la fermeture change l’appartenance aux classes à une borne. Vérifie un minimum, une borne interne et un maximum avant d’utiliser les tranches dans un rapport.
Ajouter des étiquettes lisibles
bands = pd.cut(
scores, [0, 50, 70, 85, 100],
labels=["fail", "pass", "merit", "distinction"]
)
Fournis une étiquette pour chaque intervalle : quatre étiquettes pour cinq bornes. Le résultat est une variable catégorielle ordonnée : son ordre est donc fail, pass, merit, distinction, et non l’ordre alphabétique. labels=False renvoie à la place des codes de classes allant de 0 à 3 pour les valeurs affectées, en comptant à partir de zéro.
value_counts() trie normalement selon la fréquence. Utilise sort=False ou trie l’index du résultat pour conserver l’ordre des intervalles. Sinon, la tranche la plus fréquente peut apparaître en premier et rendre la distribution plus difficile à lire.
Demander des classes de même amplitude à pandas
Passer un entier demande ce nombre de classes de même amplitude :
bands, edges = pd.cut(scores, 4, retbins=True)
L’étendue de 42 à 100 est de 58, ce qui donne des amplitudes de 14,5. Les bornes internes sont 56,5, 71,0 et 85,5. pandas étend légèrement l’extrémité inférieure pour ces classes fermées à droite, ce qui donne une première borne de 41,942 afin d’inclure le minimum. Ici, chaque classe contient par hasard trois notes ; des amplitudes égales ne produisent généralement pas des effectifs égaux.
retbins=True renvoie les bornes effectivement utilisées ainsi que les affectations. Les bornes explicites doivent être dans l’ordre croissant : [0, 70, 50, 100] ne peut pas définir la suite d’intervalles voulue.
Points clés
cuttransforme des valeurs quantitatives en catégories d’intervalles.- Par défaut, les classes excluent leur borne gauche et incluent leur borne droite.
- Avec des bornes explicites, les valeurs hors de l’étendue ne sont affectées à aucune classe.
include_lowest=Trueinclut la borne explicite la plus basse.- Un nombre entier de classes demande des amplitudes égales, et non des effectifs égaux.
- Les étiquettes et les effectifs doivent conserver l’ordre voulu des intervalles.
right=Falsemodifie la borne qui appartient à chaque intervalle ; vérifie le maximum après avoir changé la fermeture.
4.2 Créer des classes de même effectif avec les quantiles et qcut
Un quantile décrit un rang dans les données triées. La médiane est le quantile 0,5 ; les quartiles divisent la distribution en quarts, les déciles en dixièmes et les centiles en centièmes. qcut utilise les quantiles de l’échantillon comme bornes de classes.
Calculer un quantile
Pour les notes 42, 50, 55, 64, 68, 70, 73, 81, 85, 88, 97 et 100 :
scores.quantile([0.25, 0.5, 0.75])
Les résultats sont 61,75, 71,5 et 85,75. pandas utilise par défaut une interpolation linéaire. Pour le quantile 0,25, la position en comptant à partir de zéro est :
La position 2 contient 55 et la position 3 contient 64. Avance des trois quarts de la distance entre ces deux valeurs :
Un quantile d’échantillon peut donc se trouver entre des valeurs observées. Il n’est pas nécessairement égal à une note effectivement obtenue.
Créer des groupes de quantiles
quartile = pd.qcut(scores, 4, labels=["Q1", "Q2", "Q3", "Q4"])
Cet échantillon donne trois notes par groupe de quartile. Les bornes internes sont les trois quartiles calculés. Le premier intervalle inclut le minimum ; l’affichage de l’intervalle ajuste son étiquette inférieure légèrement en dessous de 42. Utilise labels=False pour obtenir les codes de 0 à 3, ou retbins=True pour récupérer les bornes numériques.
Une liste de proportions détermine les plages de quantiles. pd.qcut(x, [0, 0.1, 0.5, 0.9, 1]) sépare les 10 % inférieurs, deux parties intermédiaires séparées à la médiane et les 10 % supérieurs.
Choisir les amplitudes ou les effectifs
| Méthode | Qu’est-ce qui détermine les bornes ? | Qu’est-ce qui reste comparable ? |
|---|---|---|
cut(x, n) | Intervalles égaux sur l’étendue observée | Amplitude numérique |
cut(x, edges) | Bornes explicites fournies | Plages choisies |
qcut(x, n) | Quantiles de cet échantillon | Effectifs approximatifs |
Les durées de livraison 5, 6, 7, 7, 8, 9, 10, 12, 15, 20, 35 et 60 minutes montrent la différence. Trois classes de même amplitude contiennent 10, 1 et 1 observations. Trois classes de quantiles en contiennent 4 chacune, avec des bornes internes d’environ 7,67 et 13 minutes. Les longues attentes étendent la plage répartie en classes de même amplitude, laissant la plupart des observations dans la première classe.
Utilise des bornes fixes lorsque les mêmes plages de durée doivent être comparées entre plusieurs jeux de données. Les bornes de quantiles changent lorsque l’échantillon change.
Garder les ex æquo visibles
Pour les valeurs 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10 et 12, les bornes de quartiles sont 3,75, 6 et 8,25. Les deux valeurs 6 restent ensemble : les effectifs des classes sont donc 3, 4, 2 et 3. La discrétisation en classes de même effectif est approximative lorsque des valeurs sont ex æquo.
Lorsque les ex æquo sont nombreux, les bornes de quantiles peuvent coïncider. Pour 1, 1, 1, 1, 1, 1, 2 et 3, demander des quartiles donne des bornes répétées. duplicates="drop" supprime les bornes en double et ne laisse que deux classes, d’effectifs 6 et 2. Attribuer d’abord des rangs avec rank(method="first") peut imposer quatre groupes de même effectif, mais sépare les valeurs égales selon l’ordre des lignes. Le résultat ne représente alors plus des intervalles de valeurs, mais des groupes fondés sur des rangs où les ex æquo ont été départagés.
Points clés
- Les quantiles peuvent se trouver entre des observations, car pandas effectue une interpolation.
qcututilise les quantiles de l’échantillon pour créer des groupes d’effectifs approximativement égaux.- Utilise des bornes
cutfixes pour les plages qui doivent rester comparables entre jeux de données. - Les ex æquo peuvent rendre les effectifs des classes de quantiles inégaux ou produire des bornes en double.
- Supprimer les bornes en double réduit le nombre de classes ; attribuer d’abord des rangs départage les ex æquo.
4.3 Comparer des groupes définis par des classes et des quantiles
Une étiquette de classe peut servir de clé de groupe. Cela permet d’étudier comment une variable change selon les plages d’une autre, par exemple la note moyenne à l’examen selon les tranches d’heures d’étude. Le tableau de synthèse décrit les observations de chaque tranche.
Construire un tableau de synthèse par classes
Crée les données des étudiants :
students = pd.DataFrame({
"group": ["day", "evening", "day", "evening", "day", "evening", "day", "evening", "day", "day", "evening", "day"],
"hours": [2, 3, 3, 5, 4, 6, 6, 8, 7, 9, 10, 12],
"score": [42, 50, 55, 64, 68, 70, 73, 81, 85, 88, 97, 100]
})
hour_band = pd.cut(students["hours"], [0, 3, 6, 9, 12])
students.groupby(hour_band)["score"].agg(["count", "mean"])
Les quatre tranches contiennent 3, 4, 3 et 2 étudiants. Leurs notes moyennes sont 49, 68,75, environ 84,67 et 98,5. Dans la première tranche, les notes sont 42, 50 et 55 ; leur moyenne est 147/3 = 49. L’effectif montre combien de notes enregistrées servent au calcul de chaque moyenne.
L’objet Series des tranches contient une entrée par étudiant et le même index : les affectations correspondent donc aux lignes lors du regroupement. La colonne de nombres hours reste disponible pour d’autres calculs.
Conserver les classes vides lorsqu’un rapport en a besoin
Depuis pandas 3.0, observed=True est le réglage de regroupement par défaut pour les clés catégorielles. Ajoute une borne de 15 et la tranche inutilisée (12, 15] sera omise. observed=False la conserve avec un effectif de 0 et une moyenne NaN. Zéro étudiant est un effectif ; une moyenne nulle suggérerait à tort que les notes observées ont une moyenne de zéro.
Les classes sont des catégories ordonnées : le résultat regroupé normal suit donc l’ordre croissant des intervalles. Les étiquettes nommées conservent l’ordre attribué à leurs intervalles.
Analyser les groupes de quantiles et leurs combinaisons
quartile = pd.qcut(students["hours"], 4,
labels=["Q1", "Q2", "Q3", "Q4"])
students.groupby(quartile)["score"].agg(["count", "min", "max", "mean"])
Les effectifs sont 3, 4, 2 et 3, avec des notes moyennes de 49, 68,75, 83 et 95. Les valeurs ex æquo de 6 expliquent les effectifs inégaux. Pour comparer les étudiants de jour et du soir dans chaque quartile, regroupe selon [quartile, "group"] et appelle .mean().unstack(). Les moyennes de Q1 sont day 48,5 et evening 50 ; celles de Q4 sont day 94 et evening 97.
Le sens de l’analyse compte. Regrouper les heures d’étude par tranches de notes répond à une autre question : les moyennes d’heures pour les tranches fail, pass, merit et distinction sont 2,5, 4,5, 7 et environ 10,33.
Déterminer quelle population définit un quantile
Une séparation des notes selon la médiane globale utilise 71,5. Une séparation au sein de chaque groupe de cours utilise sa propre médiane : day 73 et evening 70.
within_class = students.groupby("group")["score"].transform(
lambda s: pd.qcut(s, 2, labels=["lower", "upper"])
)
L’étudiant de jour ayant obtenu 73 est au-dessus de la médiane globale, mais appartient à la moitié inférieure du groupe de jour. Les deux étiquettes sont correctes, car elles répondent à des questions de comparaison différentes.
Une moyenne croissante entre les tranches d’heures indique une liaison. Les étudiants des différentes tranches peuvent différer sur d’autres points : la table seule ne permet donc pas d’établir que le temps d’étude supplémentaire a causé la différence de notes. De faibles effectifs rendent aussi une moyenne plus sensible à une seule observation.
Points clés
- Utilise un objet Series de classes comme clé de groupe pour calculer un indicateur d’une autre variable.
- Indique les effectifs à côté des moyennes pour montrer la quantité de données sur laquelle elles reposent.
observed=Falseconserve les classes vides avec des effectifs nuls et des moyennes manquantes.- Les quantiles globaux et les quantiles au sein des groupes utilisent des populations de référence différentes.
- Les tendances entre classes décrivent une liaison et peuvent être sensibles aux petits échantillons.
5Synthétiser les données dans des tableaux croisés dynamiques et des tableaux de contingence
Un tableau à double entrée facilite la comparaison des combinaisons de catégories. Un tableau croisé dynamique calcule un indicateur quantitatif à chaque intersection de ligne et de colonne, tandis qu’un tableau de contingence compte généralement les observations. Les totaux et les proportions ajoutent du contexte, mais leur sens dépend de l’agrégation et du dénominateur. Tu construiras ces deux tableaux et liras chaque cellule comme une réponse à une question précise.
5.1 Construire des tableaux croisés dynamiques avec pivot_table
Un tableau croisé dynamique calcule des indicateurs pour des combinaisons de clés de lignes et de colonnes. Chaque cellule réunit les observations d’une intersection et applique une fonction, comme une somme ou une moyenne.
Attribuer explicitement les rôles
sales.pivot_table(
index="region", columns="product",
values="revenue", aggfunc="sum"
)
index fournit les clés de lignes, columns les clés de colonnes, values la variable mesurée et aggfunc le calcul. Voici le tableau :
| Région | coffee | tea |
|---|---|---|
| East | 20 | 9 |
| North | 28 | 48 |
| South | 68 | 12 |
North-tea combine les recettes 30 et 18, donc leur somme est 48. South-coffee combine 36 et 32, ce qui donne 68. Les mêmes données peuvent être synthétisées avec sales.groupby(["region", "product"])["revenue"].sum().unstack().
La valeur par défaut de aggfunc est "mean". L’omettre donnerait North-tea 24 et South-coffee 34. Indique aggfunc="sum" lorsque la question demande des totaux ; la disposition d’un tableau ne dit pas quelle statistique il contient.
Remplacer avec soin les combinaisons absentes
Les combinaisons sans observations apparaissent sous la forme NaN. Supprime la commande de thé de East et cette cellule devient manquante. fill_value=0 peut représenter l’absence de commandes dans un rapport de sommes ou d’effectifs. Pour une moyenne, remplacer une cellule vide par 0 suggère une moyenne observée qui n’a jamais été mesurée. Conserve son statut manquant lorsqu’aucune moyenne n’existe.
Les clés catégorielles suivent le réglage de observed ; depuis pandas 3.0, le réglage par défaut affiche les catégories observées. Définis-le explicitement lorsqu’un rapport doit conserver les catégories inutilisées.
Ajouter des marges avec la même fonction
sales.pivot_table(
index="region", columns="product", values="revenue",
aggfunc="sum", margins=True, margins_name="Total"
)
Les totaux des lignes sont East 29, North 76 et South 80. Les totaux des colonnes sont coffee 116 et tea 69 ; le total général est 185. margins_name remplace l’étiquette par défaut All.
Les marges sont recalculées à partir des lignes sous-jacentes avec la fonction d’agrégation. Pour un tableau de moyennes, la cellule d’angle vaut 23,125, la moyenne des huit commandes. La moyenne des six moyennes affichées dans les cellules serait d’environ 21,17, car les cellules contiennent des nombres d’observations différents. Une marge ne consiste pas systématiquement à additionner les nombres affichés ou à en calculer la moyenne.
Étendre le tableau ou compter les observations
aggfunc=["sum", "mean"] crée un bloc de colonnes pour chaque statistique. Avec units, North-tea a une somme de 16 et une moyenne de 8. Un dictionnaire de fonctions comme {"units": "sum", "revenue": "max"} attribue des fonctions à des colonnes de valeurs distinctes. Plusieurs clés peuvent aussi créer des lignes ou des colonnes hiérarchiques, et les valeurs réparties en classes fonctionnent comme des clés catégorielles.
aggfunc="size" compte les lignes par cellule, tandis que "count" compte les valeurs non manquantes dans la colonne de valeurs choisie. North compte une commande de café et deux commandes de thé.
pivot n’effectue aucune agrégation et exige des combinaisons de lignes et de colonnes uniques. La table des ventes contient plusieurs occurrences des combinaisons North-tea et South-coffee : pivot déclenche donc une erreur d’entrée en double. Utilise pivot_table lorsque plusieurs observations doivent être combinées dans une cellule.
Points clés
index,columns,valuesetaggfuncdéfinissent le sens de chaque cellule du tableau croisé dynamique.- L’agrégation par défaut est une moyenne ; demande explicitement les sommes.
- Ne remplace les effectifs ou les totaux absents par zéro que lorsque zéro exprime correctement l’absence.
- Les marges appliquent la même fonction aux observations sous-jacentes.
- Plusieurs fonctions ou valeurs peuvent produire des colonnes hiérarchiques.
- Utilise
pivot_tablepour les combinaisons de clés répétées etpivotpour les combinaisons uniques.
5.2 Compter et comparer les catégories avec crosstab
Un tableau de contingence compte les observations pour chaque combinaison de variables qualitatives. Les proportions permettent ensuite de comparer des groupes qui contiennent des nombres d’observations différents.
Compter les combinaisons
Les données de l’enquête comprennent six utilisateurs de l’offre de base : quatre utilisent un téléphone et deux un ordinateur portable. Parmi les quatre utilisateurs de l’offre premium, un utilise un téléphone et trois utilisent un ordinateur portable.
survey = pd.DataFrame({
"plan": ["basic"] * 6 + ["premium"] * 4,
"device": ["phone", "phone", "phone", "laptop", "phone", "laptop",
"laptop", "laptop", "phone", "laptop"],
"minutes": [20, 35, 15, 40, 25, 50, 60, 45, 30, 55]
})
counts = pd.crosstab(survey["plan"], survey["device"], margins=True)
Passe les objets Series eux-mêmes, et non les chaînes "plan" et "device". La première variable fournit les lignes et la seconde les colonnes. La ligne basic contient laptop 2 et phone 4 ; la ligne premium contient laptop 3 et phone 1. Les totaux des lignes sont 6 et 4, ceux des colonnes sont 5 et 5, et le total général est 10.
Pour les effectifs bruts, une combinaison absente est affichée sous la forme zéro. Des effectifs équivalents peuvent être obtenus avec survey.groupby(["plan", "device"]).size().unstack(fill_value=0) ou avec un tableau croisé dynamique utilisant aggfunc="size". survey.value_counts(["plan", "device"]) donne une liste longue de fréquences triée par effectif.
Choisir le dénominateur selon la question
| Réglage | Dénominateur | Sens de basic-phone |
|---|---|---|
normalize="all" | Toutes les observations | 4/10 = 0,4 |
normalize="index" | Total de la ligne basic | 4/6 ≈ 0,667 |
normalize="columns" | Total de la colonne phone | 4/5 = 0,8 |
« Quelle proportion des utilisateurs de l’offre premium utilise un ordinateur portable ? » part des utilisateurs de l’offre premium : le dénominateur est donc 4. Utilise une normalisation par ligne ; la réponse est 3/4 = 0,75. « Quelle proportion des utilisateurs de téléphone a l’offre de base ? » part des utilisateurs de téléphone : le dénominateur est donc 5. Utilise une normalisation par colonne ; la réponse est 4/5 = 0,8.
L’effectif de trois utilisateurs premium d’ordinateur portable dépasse celui de deux utilisateurs de l’offre de base, mais la comparaison au sein de chaque offre donne 75 % contre environ 33,3 %. Identifie la population comparée avant de transformer un effectif en proportion. Multiplie les valeurs normalisées par 100 pour obtenir des pourcentages.
Avec margins=True, les marges normalisées ont elles aussi un sens. La normalisation par ligne ajoute une ligne All qui montre les proportions globales des appareils, 0,5 et 0,5. La normalisation par colonne ajoute une colonne All qui montre les proportions globales des offres, 0,6 et 0,4.
Calculer un indicateur d’une troisième variable
Fournis values et aggfunc pour remplacer les fréquences par un indicateur quantitatif :
pd.crosstab(survey["plan"], survey["device"],
values=survey["minutes"], aggfunc="mean")
Les sessions sur ordinateur portable de l’offre de base, de 40 et 50 minutes, durent en moyenne 45 minutes. Les sessions sur téléphone de l’offre de base, de 20, 35, 15 et 25 minutes, durent en moyenne 23,75 minutes. Les sessions sur ordinateur portable de l’offre premium, de 60, 45 et 55 minutes, durent en moyenne environ 53,33 minutes, tandis que l’unique session sur téléphone de l’offre premium dure 30 minutes. Ces cellules décrivent la durée des sessions, et non les effectifs d’utilisateurs.
Une liste d’objets Series peut fournir plusieurs niveaux de lignes ou de colonnes. Les notes réparties en classes fonctionnent aussi comme catégories : le croisement de fail, pass, merit et distinction avec le groupe de cours donne les effectifs day 1, 2, 2, 2 et evening 1, 2, 1, 1. Le sens de chaque cellule découle toujours de sa clé de ligne, de sa clé de colonne et de la statistique choisie.
Points clés
crosstabcompte les combinaisons des objets Series ou des tableaux fournis.- Choisis une normalisation par ligne, par colonne ou globale selon la population qui constitue le dénominateur de la question.
- L’ajout de
valuesetaggfuncremplace les fréquences des cellules par un indicateur quantitatif.
Regroupement et agrégation avec pandas : exemples
1Transformer les lignes en groupes utiles
12 étapes
- 1IntroductionPartir d’une question par groupe
Un ensemble de commandes permet de répondre à « Combien d’unités ont été vendues ? » ou à « Combien d’unités chaque région a-t-elle vendues ? ». La deuxième question nécessite une clé de regroupement.
Nous allons répartir les commandes par région, sélectionner une colonne de valeurs et combiner les résultats par groupe. Nous modifierons ensuite les clés et la disposition du résultat tout en suivant les lignes incluses dans le calcul.
- 2ExempleCréer quatre commandes
Utilise une petite table pour pouvoir suivre chaque ligne :
orders = pd.DataFrame({ "region": ["West", "East", "West", "East"], "product": ["tea", "tea", "coffee", "tea"], "units": [6, 3, 8, 5] })Les deux lignes West sont séparées par une ligne East. Elles appartiennent néanmoins au même groupe lorsque la clé est la région ; l’égalité des clés compte plus que la proximité des lignes.
- 3ExplicationSéparer, additionner, combiner
orders.groupby("region")["units"].sum()East reçoit les unités 3 et 5, ce qui donne 8. West reçoit 6 et 8, ce qui donne 14. pandas combine les deux totaux dans un objet Series indexé par région.
Appeler seulement
groupby("region")crée l’objet GroupBy. La sélection etsum()précisent ce qu’il faut calculer à partir de ce regroupement. - 4ConseilExaminer avant de calculer
Enregistre
g = orders.groupby("region")lorsque plusieurs vérifications sont utiles.g.ngroupsindique 2,g.size()indique deux lignes par région etg.get_group("West")montre les observations West.Sélectionner
g["units"]produit un SeriesGroupBy. Sélectionnerg[["units"]]conserve la forme d’un DataFrame, même si une seule colonne de valeurs est sélectionnée. - 5DéfiPrévoir un total modifié
Une nouvelle commande West de 4 unités est ajoutée à la table. Quels sont les totaux régionaux et le regroupement supprime-t-il les lignes de commandes d’origine ?
---reveal---
East reste à 8. West passe à 18, car la nouvelle commande s’ajoute aux 14 unités existantes. Les lignes d’origine restent dans la table d’entrée ; la somme par groupe est un nouvel objet de synthèse comportant une entrée par région.
- 6ExempleAjouter une deuxième clé
orders.groupby(["region", "product"])["units"].sum()Avec les quatre commandes d’origine, East-tea totalise 8, West-coffee totalise 8 et West-tea totalise 6. L’objet Series possède un index à deux niveaux.
unstack()déplace le produit vers les colonnes. East n’a aucune ligne de café, donc sa cellule coffee est manquante ; la remplacer par zéro convient à ce rapport de totaux d’unités. - 7LienUne clé peut être calculée
orders.groupby(orders["units"] >= 5)["units"].sum()La clé booléenne crée un groupe
Falsetotalisant 3 et un groupeTruetotalisant 19. Elle attribue une étiquette à chaque ligne au lieu de filtrer les petites commandes.Un objet Series issu d’une correspondance peut aussi servir de clé. Les clés de type Series s’alignent selon les étiquettes de lignes, tandis qu’un tableau fournit une étiquette par position et doit correspondre au nombre de lignes.
- 8DéfiLire une clé à partir de l’index
Un objet Series de stock est indexé par M1, N1, M2, avec les valeurs 4, 9, 7. Que renvoie
stock.groupby(lambda label: label[0]).sum()?---reveal---
M totalise 11 et N totalise 9. La fonction reçoit chaque étiquette d’index et renvoie sa première lettre. Elle n’examine pas la valeur du stock. Un dictionnaire passé directement comme clé établit lui aussi une correspondance avec les étiquettes d’index ; établis d’abord la correspondance sur une colonne lorsque ses valeurs définissent les groupes.
- 9ExplicationChoisir les étiquettes et l’ordre
orders.groupby("region", as_index=False)["units"].sum()renvoie une table avec les colonnes region et units.reset_index()convertit un tableau de synthèse indexé dans la même disposition sans index hiérarchique.Le tri des clés par défaut place East avant West. Pour classer les totaux, trie plutôt les valeurs calculées :
.sum().sort_values(ascending=False). L’ordre des clés et celui des valeurs répondent à des besoins différents. - 10Point cléDistinguer clés manquantes et clés inutilisées
Supposons que la région soit catégorielle et déclare aussi North, sans aucune commande North. Depuis pandas 3.0, le réglage par défaut
observed=Trueomet cette catégorie inutilisée ;observed=Falsel’affiche.Une ligne sans région est un cas distinct. Le réglage par défaut
dropna=Truel’exclut des groupes.dropna=Falseconserve un groupe de clés manquantes. Une option ne peut pas remplacer l’autre. - 11DéfiFaire concorder les totaux du rapport
Les quatre commandes d’origine totalisent 22 unités. Une cinquième commande comporte 7 unités et aucune région. Une colonne catégorielle de région déclare aussi une catégorie North inutilisée. Comment obtenir un rapport totalisant 29 et affichant North ?
---reveal---
Regroupe avec
dropna=False, observed=False. Le groupe de clés manquantes conserve les 7 unités supplémentaires ; North apparaît comme catégorie inutilisée avec une somme de 0. Utilise aussias_index=Falsesi le rapport nécessite des colonnes de clés ordinaires. - 12RécapitulatifVérifier les clés, les valeurs et la forme
Choisis la clé qui détermine quelles lignes vont ensemble, puis choisis l’opération et les colonnes de valeurs à sélectionner. Examine les groupes lorsque l’appartenance des lignes n’est pas claire.
Après avoir calculé un total, vérifie si des clés manquantes ont entraîné l’exclusion de lignes. Pour la présentation, choisis entre un résultat indexé et des colonnes de clés ordinaires, et distingue le tri des noms de groupes du classement des valeurs calculées.
2Choisir et nommer les indicateurs par groupe
13 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionUn indicateur doit répondre à une question
- 2ExempleSuivre un lot comportant une valeur manquante
- 3ExplicationComprendre les réglages par défaut des réductions
- 4DéfiCompter les mesures disponibles
- 5ExempleNommer chaque résultat
- 6ExplicationComprendre les colonnes obtenues avec plusieurs fonctions
- 7DéfiCorriger les noms du rapport
- 8ExempleAjouter une étendue personnalisée
- 9ConseilPréparer une colonne booléenne
- 10ExemplePondérer la quantité mesurée
- 11DéfiTrouver le prix par unité
- 12DéfiCombiner des moyennes de groupes d’effectifs différents
- 13RécapitulatifGarder le sens de chaque statistique explicite
3Associer le contexte du groupe aux bonnes lignes
16 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionDéterminer les lignes nécessaires à la réponse
- 2ExempleDiffuser un total
- 3ExempleTransformer les totaux en proportions
- 4DéfiChoisir la bonne valeur de remplacement
- 5ExplicationÉtablir d’abord la séquence
- 6ExempleComparer à l’observation précédente
- 7ConseilChoisir la règle pour les ex æquo
- 8DéfiSuivre des groupes dont les lignes sont intercalées
- 9ExempleConserver toutes les lignes d’un groupe admissible
- 10ConseilSélectionner ou échantillonner au sein des groupes
- 11DéfiAppliquer une condition à un groupe entier
- 12ExplicationPrévoir la forme du résultat de apply
- 13ExempleRenvoyer plusieurs lignes par groupe
- 14DéfiCorriger l’affectation aux lignes
- 15DéfiCombiner un total de groupe et une décision par ligne
- 16RécapitulatifAdapter la méthode au résultat
4Construire et comparer des tranches numériques
14 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionChoisir le sens d’une tranche
- 2ExempleCréer des intervalles fixes
- 3ExplicationCouvrir les valeurs extrêmes
- 4ConseilConserver les étiquettes dans l’ordre des intervalles
- 5DéfiPlacer les valeurs situées aux bornes
- 6ExplicationTrouver un quantile d’échantillon
- 7ExempleRépartir selon l’effectif ou l’amplitude
- 8Point cléLes ex æquo peuvent modifier le nombre de classes
- 9DéfiChoisir des bornes stables
- 10ExempleCalculer un indicateur d’une autre variable
- 11ConseilAfficher correctement les groupes vides
- 12DéfiChanger la population de référence
- 13DéfiLire la comparaison finale
- 14RécapitulatifLire les plages avant de comparer les résultats
5Lire les totaux et les proportions dans un tableau à double entrée
11 étapes
Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.
- 1IntroductionDonner un sens à chaque cellule
- 2ExempleConstruire un petit tableau croisé dynamique
- 3ExplicationPréciser l’agrégation
- 4Point cléLes marges utilisent les observations sous-jacentes
- 5DéfiPrésenter les absences et les totaux
- 6ExempleCompter les combinaisons de catégories
- 7ExplicationCommencer par le dénominateur
- 8DéfiComparer des groupes d’effectifs différents
- 9LienUn tableau de contingence peut calculer des indicateurs
- 10DéfiChoisir le tableau adapté à un rapport
- 11RécapitulatifLire ensemble la fonction et la population
Regroupement et agrégation avec pandas : QCM
Série 1 : Utiliser le contexte des lignes et comparer des distributions10 Questions Pratiques
Question 1 sur 10
g a déjà été créé. Quelle expression indique le nombre de groupes qu’il contient ?Afficher la réponseMasquer la réponse
ngroups est le nombre de groupes d’un objet GroupBy. size() renvoie quant à lui un nombre de lignes distinct pour chaque groupe. count() renvoie aussi des résultats par groupe, mais compte les valeurs enregistrées dans chaque colonne sélectionnée au lieu d’indiquer un nombre de groupes.Question 2 sur 10
Afficher la réponseMasquer la réponse
Question 3 sur 10
Afficher la réponseMasquer la réponse
Question 4 sur 10
lambda s: s.max() - s.min() ?Afficher la réponseMasquer la réponse
Question 5 sur 10
Afficher la réponseMasquer la réponse
Question 6 sur 10
delay enregistré est inférieur à 4. Quel prédicat donne une décision par groupe ?Afficher la réponseMasquer la réponse
all() combine les comparaisons des lignes en une seule valeur booléenne et exige que toutes soient vraies. any() conserverait un atelier même si une seule attente était inférieure à 4. Renvoyer l’objet Series des comparaisons lui-même ne donne pas la décision unique par groupe exigée par filter.Question 7 sur 10
apply par groupe renvoie pour chaque groupe un objet Series indexé par low et high. Quelle structure pandas construit-il ?Afficher la réponseMasquer la réponse
low et high. Un résultat ayant le nombre de lignes d’entrée d’origine nécessiterait une opération alignée sur les lignes ; cette fonction fournit deux indicateurs par groupe au lieu d’une valeur pour chaque ligne d’entrée.Question 8 sur 10
Afficher la réponseMasquer la réponse
qcut utilise les quantiles de l’échantillon pour former des groupes d’effectifs approximativement égaux. Les ex æquo peuvent empêcher les effectifs d’être exactement égaux. cut(times, 4) crée à la place des intervalles de même amplitude, qui peuvent avoir des nombres d’observations très différents lorsque la distribution des durées de livraison est irrégulière.Question 9 sur 10
Afficher la réponseMasquer la réponse
Question 10 sur 10
All pour P et Q ?Afficher la réponseMasquer la réponse
All décrit la distribution des colonnes dans l’ensemble de l’échantillon. Il y a cinq observations P et sept observations Q sur douze : elle montre donc 5/12 et 7/12. La moyenne des proportions des deux lignes donnerait 0,5 et 0,5, en attribuant à tort le même poids aux groupes de huit et de quatre lignes.Série 2 : Lire les groupes et choisir des indicateurs utiles10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
site et material. Comment regrouper les données selon chaque combinaison de ces deux colonnes ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
site et mass_kg comme colonnes ordinaires. Quel appel produit cette disposition ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
size() et le count() des mesures ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
peak et average calculées à partir de load. Quelle agrégation nommée convient ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
pd.cut(x, [0, 20, 40, 60]) et la fermeture par défaut ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
pivot_table si aggfunc est omis ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 3 : Vérifier la forme des résultats et le choix des bornes10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
["sum", "mean"]. Quelles étiquettes portent les colonnes du résultat ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
pct_change() par groupe ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
mass_kg pour chaque batch. Quelle procédure convient ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
f trie chaque groupe selon la qualité et renvoie deux lignes. Avec df.groupby("batch", group_keys=False).apply(f), à quoi dois-tu t’attendre avant de réaffecter le résultat ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
pd.cut(x, [0, 10, 20], right=False). Parmi les valeurs 0, 10 et 20, lesquelles sont affectées à une classe ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
qcut(..., 4, duplicates="drop") par rapport à une attribution préalable de rangs avec method="first" ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 4 : Construire des rapports fiables par groupe10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
g = df.groupby("team")[["items"]]. Quel objet g.sum() renvoie-t-il ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
dropna=False, quelles sommes par groupe obtient-on ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
std() par groupe avec les réglages par défaut ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
True, False pour l’usine A et True, True, False, False, False, False pour l’usine B. Quelle proportion de l’ensemble des articles inspectés est défectueuse ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Série 5 : Diagnostiquer des analyses et des comparaisons par groupe10 Questions Pratiques
Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.
Question 1 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 2 sur 10
.agg("std") et .agg(np.std) peuvent-ils donner des résultats différents ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 3 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 4 sur 10
apply sur un DataFrame regroupé peut-elle lire la clé de son groupe courant ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 5 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 6 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 7 sur 10
apply(lambda s: s - s.mean()) sur un objet Series de nombres regroupé, puis réinitialise l’index du résultat et affecte ses valeurs par position à la table d’origine non triée. Pourquoi la nouvelle colonne peut-elle être erronée ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 8 sur 10
len(s) sur les valeurs 5, valeur manquante, 7. Que renvoie-t-elle et que mesure ce nombre ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 9 sur 10
Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Question 10 sur 10
fill_value=0 peut-il induire le lecteur en erreur ?Afficher la réponseMasquer la réponse
Enregistre cette unité pour voir cette réponse.
Tu bloques sur ton propre exercice ? Aide aux Devoirs
Mots-Clés
A
Agrégation
Agrégation nommée
total_mass à partir d’une somme et max_temperature à partir d’un maximum dans un même rapport.Agrégation personnalisée
Alignement des index
Analyse par classes
Analyse par quantiles
apply
B
Borne de classe
C
Catégorie inutilisée
observed=False est choisi.Catégories observées
Classe de quantiles
Classes de même amplitude
Clé de regroupement
Clé manquante
dropna=False.Clés de groupe
apply.Colonnes hiérarchiques
Combinaison de clés en double
pivot_table avant de pouvoir occuper une seule cellule numérique.Correspondance
D
Degrés de liberté
Désempilement
Dictionnaire d’agrégation
Diffusion
transform donne à chaque ligne le dénominateur de sa propre proportion.Discrétisation
É
Écart à la moyenne du groupe
Écart-type d’échantillon
Échantillon par groupe
n=1 inclut un enregistrement de chaque région non vide au lieu de risquer d’omettre des régions.E
Ex æquo
Expression lambda
F
Filtrage
Filtre de groupes
Fonction appliquée à un groupe
apply par groupe peut lui fournir plusieurs colonnes ensemble.Fonction d’agrégation
I
Interpolation linéaire
Intervalle fermé à droite
cut par défaut excluent la borne gauche et incluent la borne droite.(20, 40] contient la valeur 40 mais exclut la valeur 20.L
Liaison statistique
M
Marge
Médiane
Moyenne de valeurs booléennes
Moyenne pondérée
MultiIndex
N
Nombre de lignes
Nombre de valeurs distinctes
nunique() exclut les valeurs manquantes par défaut.Nombre de valeurs non manquantes
Normalisation
O
Objet appelable
np.std peut utiliser un diviseur par défaut différent de celui de la fonction pandas appelée par la chaîne "std".Objet GroupBy
P
Population de référence
Prédicat
all() peut exiger que chaque mesure d’un groupe satisfasse la même condition de qualité.Proportion en colonne
Proportion en ligne
Proportion globale
Q
Quantile
Quartile
qcut de répartir les observations en quatre groupes d’effectifs approximativement égaux.R
Rang au sein du groupe
Rang dense
Résultat scalaire
apply par groupe combine dans un objet Series indexé par les clés de groupe.S
Score z au sein du groupe
Sélection des n plus grandes valeurs
head(2) par groupe.Séparer-appliquer-combiner
Somme cumulée
T
Tableau croisé dynamique
Tableau de contingence
Tableau de synthèse sans index hiérarchique
Transformation
V
Valeur de remplacement
Valeur retardée
Variable catégorielle ordonnée
Variation relative
À propos de cette unité
Crée ton propre Matériel d'Étude
Transforme tes notes, diapos et documents en Guides d'Étude, Questions Pratiques, Flashcards et 6 autres outils.