Maîtrisez le remodelage des données avec les tableaux croisés dynamiques Python Pandas. Analyse approfondie de la syntaxe, des techniques avancées et des exemples pratiques.
Tableaux croisés dynamiques Python Pandas : Un guide complet du remodelage des données
Dans le monde de l'analyse des données, la capacité de résumer, d'agréger et de restructurer les données n'est pas seulement une compétence, c'est une superpuissance. Les données brutes, dans leur forme native, ressemblent souvent à un grand livre détaillé et tentaculaire. Elles sont riches en informations mais difficiles à interpréter. Pour extraire des informations significatives, nous devons transformer ce grand livre en un résumé concis. C'est précisément là que les tableaux croisés dynamiques excellent, et pour les programmeurs Python, la bibliothèque Pandas fournit un outil puissant et flexible : pivot_table().
Ce guide est conçu pour un public mondial d'analystes de données, de scientifiques et de passionnés de Python. Nous allons plonger en profondeur dans les mécanismes des tableaux croisés dynamiques Pandas, en passant des concepts fondamentaux aux techniques avancées. Que vous résumiez les chiffres de vente de différents continents, que vous analysiez les données climatiques dans différentes régions ou que vous suiviez les mesures de projet pour une équipe répartie, la maîtrise des tableaux croisés dynamiques changera fondamentalement votre façon d'aborder l'exploration des données.
Qu'est-ce qu'un tableau croisé dynamique exactement ?
Si vous avez déjà utilisé un tableur tel que Microsoft Excel ou Google Sheets, vous connaissez probablement le concept de tableau croisé dynamique. Il s'agit d'un tableau interactif qui vous permet de réorganiser et de résumer les colonnes et les lignes de données sélectionnées à partir d'un ensemble de données plus volumineux afin d'obtenir un rapport souhaité.
Un tableau croisé dynamique fait deux choses essentielles :
- Agrégation : il calcule une statistique récapitulative (telle qu'une somme, une moyenne ou un nombre) pour les données numériques regroupées par une ou plusieurs catégories.
- Remodelage : il transforme les données d'un format « long » en un format « large ». Au lieu d'avoir toutes les valeurs dans une seule colonne, il « pivote » les valeurs uniques d'une colonne dans de nouvelles colonnes dans la sortie.
La fonction pivot_table() de Pandas apporte cette puissante fonctionnalité directement dans votre flux de travail d'analyse de données Python, permettant un remodelage des données reproductible, scriptable et évolutif.
Configuration de votre environnement et exemples de données
Avant de commencer, assurez-vous que la bibliothèque Pandas est installée. Si ce n'est pas le cas, vous pouvez l'installer à l'aide de pip, le programme d'installation de packages de Python :
pip install pandas
Maintenant, importons-le dans notre script Python ou notre notebook :
import pandas as pd
import numpy as np
Création d'un ensemble de données de ventes mondiales
Pour rendre nos exemples pratiques et pertinents à l'échelle mondiale, nous allons créer un ensemble de données synthétiques représentant les données de ventes d'une société multinationale de commerce électronique. Cet ensemble de données comprendra des informations sur les ventes provenant de différentes régions, pays et catégories de produits.
# Create a dictionary of data
data = {
'TransactionID': range(1, 21),
'Date': pd.to_datetime([
'2023-01-15', '2023-01-16', '2023-01-17', '2023-02-10', '2023-02-11',
'2023-02-12', '2023-03-05', '2023-03-06', '2023-03-07', '2023-01-20',
'2023-01-21', '2023-02-15', '2023-02-16', '2023-03-10', '2023-03-11',
'2023-01-18', '2023-02-20', '2023-03-22', '2023-01-25', '2023-02-28'
]),
'Region': [
'North America', 'Europe', 'Asia', 'North America', 'Europe', 'Asia', 'North America', 'Europe', 'Asia', 'Europe',
'Asia', 'North America', 'Europe', 'Asia', 'North America', 'Asia', 'Europe', 'North America', 'Europe', 'Asia'
],
'Country': [
'USA', 'Germany', 'Japan', 'Canada', 'France', 'India', 'USA', 'UK', 'China', 'Germany',
'Japan', 'USA', 'France', 'India', 'Canada', 'China', 'UK', 'USA', 'Germany', 'India'
],
'Product_Category': [
'Electronics', 'Apparel', 'Electronics', 'Books', 'Apparel', 'Electronics', 'Books', 'Electronics', 'Apparel',
'Apparel', 'Books', 'Electronics', 'Books', 'Apparel', 'Electronics', 'Books', 'Apparel', 'Books', 'Electronics', 'Electronics'
],
'Units_Sold': [10, 5, 8, 20, 7, 12, 15, 9, 25, 6, 30, 11, 18, 22, 14, 28, 4, 16, 13, 10],
'Unit_Price': [1200, 50, 900, 15, 60, 1100, 18, 950, 45, 55, 12, 1300, 20, 40, 1250, 14, 65, 16, 1150, 1050]
}
# Create DataFrame
df = pd.DataFrame(data)
# Calculate Revenue
df['Revenue'] = df['Units_Sold'] * df['Unit_Price']
# Display the first few rows of the DataFrame
print(df.head())
Cet ensemble de données nous donne une base solide avec un mélange de données catégorielles (Region, Country, Product_Category), de données numériques (Units_Sold, Revenue) et de données de séries chronologiques (Date).
L'anatomie de pivot_table()
La fonction pivot_table() de Pandas est incroyablement polyvalente. Décomposons ses paramètres les plus importants :
pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, margins_name='All')
- data : le DataFrame que vous souhaitez faire pivoter.
- values : la ou les colonnes contenant les données à agréger. S'il n'est pas spécifié, toutes les colonnes numériques restantes seront utilisées.
- index : la ou les colonnes dont les valeurs uniques formeront les lignes du nouveau tableau croisé dynamique. On l'appelle parfois la « clé de regroupement ».
- columns : la ou les colonnes dont les valeurs uniques seront « pivotées » pour former les colonnes du nouveau tableau.
- aggfunc : la fonction d'agrégation à appliquer aux « values ». Il peut s'agir d'une chaîne telle que « sum », « mean », « count », « min », « max » ou d'une fonction telle que
np.sum. Vous pouvez également transmettre une liste de fonctions ou un dictionnaire pour appliquer différentes fonctions à différentes colonnes. La valeur par défaut est « mean ». - fill_value : une valeur pour remplacer les résultats manquants (NaN) dans le tableau croisé dynamique.
- margins : un booléen. Si la valeur est définie sur
True, il ajoute des sous-totaux pour les lignes et les colonnes (également appelés total général). - margins_name : le nom de la ligne/colonne qui contient les totaux lorsque
margins=True. La valeur par défaut est « All ».
Votre premier tableau croisé dynamique : un exemple simple
Commençons par une question commerciale courante : « Quel est le chiffre d'affaires total généré par chaque catégorie de produits ? »
Pour répondre à cette question, nous devons :
- Utiliser
Product_Categorypour les lignes (index). - Agréger la colonne
Revenue(values). - Utiliser la somme comme fonction d'agrégation (aggfunc).
# Simple pivot table to see total revenue by product category
category_revenue = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
aggfunc='sum')
print(category_revenue)
Sortie :
Revenue
Product_Category
Apparel 1645
Books 1184
Electronics 56850
Instantanément, nous avons un résumé clair et concis. Le journal des transactions brut de 20 lignes a été remodelé en un tableau de 3 lignes qui répond directement à notre question. C'est la puissance fondamentale d'un tableau croisé dynamique.
Ajout d'une dimension de colonne
Maintenant, développons cela. Et si nous voulons voir le chiffre d'affaires total par catégorie de produits, mais également ventilé par région ? C'est là que le paramètre columns entre en jeu.
# Pivot table with index and columns
revenue_by_category_region = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum')
print(revenue_by_category_region)
Sortie :
Region Asia Europe North America Product_Category Apparel 1125.0 625.0 NaN Books 336.0 360.0 488.0 Electronics 13200.0 14550.0 29100.0
Cette sortie est beaucoup plus riche. Nous avons pivoté les valeurs uniques de la colonne « Region » (« Asia », « Europe », « North America ») dans de nouvelles colonnes. Nous pouvons maintenant facilement comparer les performances des différentes catégories de produits dans différentes régions. Nous voyons également une valeur NaN (Not a Number). Cela indique qu'il n'y a pas eu de ventes de « Apparel » enregistrées pour « North America » dans notre ensemble de données. Il s'agit d'une information précieuse en soi !
Techniques de pivotement avancées
Les bases sont puissantes, mais la véritable flexibilité de pivot_table() se révèle dans ses fonctionnalités avancées.
Gestion des valeurs manquantes avec fill_value
La valeur NaN dans notre tableau précédent est exacte, mais à des fins de création de rapports ou de calculs supplémentaires, il pourrait être préférable de l'afficher sous la forme zéro. Le paramètre fill_value facilite cela.
# Using fill_value to replace NaN with 0
revenue_by_category_region_filled = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum',
fill_value=0)
print(revenue_by_category_region_filled)
Sortie :
Region Asia Europe North America Product_Category Apparel 1125 625 0 Books 336 360 488 Electronics 13200 14550 29100
Le tableau est maintenant plus propre et plus facile Ă lire, en particulier pour un public non technique.
Utilisation de plusieurs index (indexation hiérarchique)
Que faire si vous devez regrouper par plus d'une catégorie sur les lignes ? Par exemple, décomposons les ventes par Region, puis par Country dans chaque région. Nous pouvons transmettre une liste de colonnes au paramètre index.
# Multi-level pivot table using a list for the index
multi_index_pivot = pd.pivot_table(df,
values='Revenue',
index=['Region', 'Country'],
aggfunc='sum',
fill_value=0)
print(multi_index_pivot)
Sortie :
Revenue
Region Country
Asia China 488
India 1760
Japan 10860
Europe France 1020
Germany 14440
UK 1115
North America Canada 17800
USA 12058
Pandas a automatiquement créé un MultiIndex sur les lignes. Cette structure hiérarchique est fantastique pour explorer vos données en profondeur et voir les relations imbriquées. Vous pouvez appliquer la même logique au paramètre columns pour créer des colonnes hiérarchiques.
Utilisation de plusieurs fonctions d'agrégation
Parfois, une seule statistique récapitulative ne suffit pas. Vous souhaiterez peut-être voir à la fois le chiffre d'affaires total (somme) et la taille moyenne des transactions (moyenne) pour chaque groupe. Vous pouvez transmettre une liste de fonctions à aggfunc.
# Using multiple aggregation functions
multi_agg_pivot = pd.pivot_table(df,
values='Revenue',
index='Region',
aggfunc=['sum', 'mean', 'count'])
print(multi_agg_pivot)
Sortie :
sum mean count
Revenue Revenue Revenue
Region
Asia 13108.000000 2184.666667 6
Europe 16575.000000 2762.500000 6
North America 29858.000000 4976.333333 6
Cette commande unique nous donne un résumé complet : le chiffre d'affaires total, le chiffre d'affaires moyen par transaction et le nombre de transactions pour chaque région. Notez comment Pandas crée des colonnes hiérarchiques pour maintenir la sortie organisée.
Application de différentes fonctions à différentes valeurs
Vous pouvez devenir encore plus précis. Imaginez que vous voulez voir la somme de Revenue mais la moyenne de Units_Sold. Vous pouvez transmettre un dictionnaire à aggfunc où les clés sont les noms de colonnes (« values ») et les valeurs sont les fonctions d'agrégation souhaitées.
# Different aggregations for different values
dict_agg_pivot = pd.pivot_table(df,
index='Region',
values=['Revenue', 'Units_Sold'],
aggfunc={
'Revenue': 'sum',
'Units_Sold': 'mean'
},
fill_value=0)
print(dict_agg_pivot)
Sortie :
Revenue Units_Sold
Region
Asia 13108 17.833333
Europe 16575 8.166667
North America 29858 14.333333
Ce niveau de contrôle est ce qui fait de pivot_table() un outil de premier plan pour l'analyse de données sophistiquée.
Calcul des totaux généraux avec margins
À des fins de création de rapports, il est souvent essentiel d'avoir des totaux de lignes et de colonnes. L'argument margins=True fournit cela sans effort supplémentaire.
# Adding totals with margins=True
revenue_with_margins = pd.pivot_table(df,
values='Revenue',
index='Product_Category',
columns='Region',
aggfunc='sum',
fill_value=0,
margins=True,
margins_name='Grand Total') # Custom name for totals
print(revenue_with_margins)
Sortie :
Region Asia Europe North America Grand Total Product_Category Apparel 1125 625 0 1750 Books 336 360 488 1184 Electronics 13200 14550 29100 56850 Grand Total 14661 15535 29588 59784
Pandas calcule automatiquement la somme pour chaque ligne (le chiffre d'affaires total par catégorie de produits dans toutes les régions) et chaque colonne (le chiffre d'affaires total par région dans toutes les catégories), plus un total général pour toutes les données dans le coin inférieur droit.
Cas d'utilisation pratique : analyse temporelle
Les tableaux croisés dynamiques ne se limitent pas aux catégories statiques. Ils sont incroyablement utiles pour analyser les données de séries chronologiques. Trouvons le chiffre d'affaires total pour chaque mois.
Tout d'abord, nous devons extraire le mois de notre colonne « Date ». Nous pouvons utiliser l'accesseur .dt dans Pandas pour cela.
# Extract month from the Date column
df['Month'] = df['Date'].dt.month_name()
# Pivot to see monthly revenue by product category
monthly_revenue = pd.pivot_table(df,
values='Revenue',
index='Month',
columns='Product_Category',
aggfunc='sum',
fill_value=0)
# Optional: Order the months correctly
month_order = ['January', 'February', 'March']
monthly_revenue = monthly_revenue.reindex(month_order)
print(monthly_revenue)
Sortie :
Product_Category Apparel Books Electronics Month January 250 360 23100 February 795 794 24250 March 705 30 9500
Ce tableau nous donne une vue claire des performances de vente de chaque catégorie au fil du temps, nous permettant de repérer facilement les tendances, la saisonnalité ou les anomalies.
pivot_table() vs. groupby() : quelle est la différence ?
Il s'agit d'une question courante pour ceux qui apprennent Pandas. Les deux fonctions sont étroitement liées, et en fait, pivot_table() est construit au-dessus de groupby().
groupby()est une opération plus générale et fondamentale. Il regroupe les données en fonction de certains critères, puis vous permet d'appliquer une fonction d'agrégation. Le résultat est généralement une série Pandas ou un DataFrame avec un index hiérarchique, mais il reste dans un format « long ».pivot_table()est un outil spécialisé qui effectue un group-by, puis remodèle les données. Son objectif principal est de transformer les données d'un format long en un format large, qui est souvent plus lisible.
Revenons Ă notre premier exemple en utilisant groupby()Â :
# Same result as our first pivot table, but using groupby
category_revenue_groupby = df.groupby('Product_Category')['Revenue'].sum()
print(category_revenue_groupby)
Le résultat est une série Pandas qui est fonctionnellement équivalente au DataFrame de notre premier tableau croisé dynamique. Cependant, lorsque vous introduisez une deuxième clé de regroupement (comme « Region »), la différence devient claire.
# Grouping by two columns
groupby_multi = df.groupby(['Product_Category', 'Region'])['Revenue'].sum()
print(groupby_multi)
Sortie (une série avec un MultiIndex) :
Product_Category Region
Apparel Asia 1125
Europe 625
Books Asia 336
Europe 360
North America 488
Electronics Asia 13200
Europe 14550
North America 29100
Name: Revenue, dtype: int64
Pour obtenir le même format « large » que pivot_table(index='Product_Category', columns='Region'), vous devez utiliser groupby() suivi de unstack() :
# Replicating a pivot table with groupby().unstack()
groupby_unstack = df.groupby(['Product_Category', 'Region'])['Revenue'].sum().unstack(fill_value=0)
print(groupby_unstack)
Cela produit exactement la même sortie que notre tableau croisé dynamique avec des colonnes. Ainsi, vous pouvez considérer pivot_table() comme un raccourci pratique pour le flux de travail courant groupby().aggregate().unstack().
Quand utiliser lequel ?
- Utilisez
pivot_table()lorsque vous souhaitez une sortie en format large et lisible, en particulier pour la création de rapports ou la création de tableaux croisés. - Utilisez
groupby()lorsque vous avez besoin de plus de flexibilité, que vous effectuez des calculs intermédiaires dans un pipeline de traitement de données ou lorsque le format large remodelé n'est pas votre objectif final.
Performances et meilleures pratiques
Bien que pivot_table() soit puissant, il est important de l'utiliser efficacement, en particulier avec de grands ensembles de données.
- Filtrer d'abord, pivoter ensuite : si vous n'avez besoin d'analyser qu'un sous-ensemble de vos données (par exemple, les ventes de la dernière année), filtrez le DataFrame avant d'appliquer le tableau croisé dynamique. Cela réduit la quantité de données que la fonction doit traiter.
- Utiliser des types catégoriels : pour les colonnes que vous utilisez fréquemment comme index ou colonnes dans vos tableaux croisés dynamiques (comme « Region » ou « Product_Category »), convertissez-les en type « category » dans Pandas. Cela peut réduire considérablement l'utilisation de la mémoire et accélérer les opérations de regroupement.
df['Region'] = df['Region'].astype('category') - Gardez-le lisible : évitez de créer des tableaux croisés dynamiques avec trop d'index et de colonnes. Bien que cela soit possible, un tableau croisé dynamique qui fait des centaines de colonnes de large et des milliers de lignes de long peut devenir tout aussi illisible que les données brutes d'origine. Utilisez-le pour créer des résumés ciblés.
- Comprendre l'agrégation : soyez attentif à votre choix de
aggfunc. L'utilisation de « sum » sur les prix n'a pas de sens, tandis que « mean » pourrait être plus approprié. Assurez-vous toujours que votre agrégation correspond à la question à laquelle vous essayez de répondre.
Conclusion : votre outil pour des résumés perspicaces
La fonction pivot_table() de Pandas est un outil indispensable dans la boîte à outils de tout analyste de données. Elle fournit un moyen déclaratif, expressif et puissant de passer de données désordonnées et détaillées à des résumés propres et perspicaces. En comprenant et en maîtrisant ses composants de base — values, index, columns et aggfunc — et en tirant parti de ses fonctionnalités avancées telles que l'indexation à plusieurs niveaux, les agrégations personnalisées et les marges, vous pouvez remodeler vos données pour répondre à des questions commerciales complexes avec seulement quelques lignes de code Python.
La prochaine fois que vous serez confronté à un grand ensemble de données, résistez à l'envie de faire défiler des lignes interminables. Pensez plutôt aux questions auxquelles vous devez répondre et à la façon dont un tableau croisé dynamique peut remodeler vos données pour révéler les histoires cachées à l'intérieur. Bon pivotement !