Accéder au contenu principal

Groupby, split-apply-combine et pandas

Dans ce tutoriel, vous apprendrez à utiliser l'opération groupby de pandas, qui s'appuie sur la stratégie split-apply-combine, sur des données de films Netflix.
Actualisé 19 sept. 2026  · 8 min lire

Explorer avec l’IA

ChatGPTClaudePerplexity

Netflix a récemment publié des données d'évaluation des utilisateurs. Je me suis posé une question simple : les abonnés Netflix préfèrent-ils les films anciens ou récents ?

Intuitivement, vous voulez scinder le jeu de données en groupes, un par année, puis calculer une statistique synthétique, comme la moyenne ou la médiane, et observer si cette statistique augmente au fil des années (vous pourrez ensuite réaliser un test statistique).

La bonne nouvelle, c'est qu'il existe un cadre conceptuel pour faire et penser cela, avec des implémentations en Python comme en R. Ce cadre est connu sous le nom de « split-apply-combine » (scinder–appliquer–combiner) car nous…

  • Étape 1 : scinder les données en groupes en créant un objet groupby à partir du DataFrame d'origine ;
  • Étape 2 : appliquer une fonction, ici une fonction d'agrégation qui calcule une statistique synthétique (vous pouvez aussi transformer ou filtrer vos données à cette étape) ;
  • Étape 3 : combiner les résultats dans un nouveau DataFrame.

Voici donc le cadre conceptuel pour l'analyse qui nous intéresse. Dans cet article, vous apprendrez à l'appliquer pour répondre à la question des notes Netflix ci-dessus à l'aide du paquet Python pandas. Vous pourriez faire la même chose en R avec, par exemple, le paquet dplyr. J'aborderai aussi les objets groupby, qui ne sont pas les plus intuitifs. Le processus split-apply-combine avec des objets groupby correspond à un schéma que nous suivons tous instinctivement, comme nous le verrons, mais il a fallu Hadley Wickham pour formaliser la procédure en 2011 dans son article The Split-Apply-Combine Strategy for Data Analysis.

Si vous trouvez cette technique utile, vous pouvez en apprendre davantage (entre autres) et vous entraîner dans notre cours Manipulating DataFrames with pandas.

Exploration des données avec pandas

Importez vos données

Ici, vous utiliserez pandas, les objets groupby et les principes du split-apply-combine pour analyser l'évolution des notes des films Netflix en fonction de leur année de sortie. J'ai initialement trouvé les données sur data.world ici. Vous pouvez retrouver tout le code de ce billet ici si vous souhaitez le reproduire.

Commencez par importer les packages nécessaires et les données, puis affichez les cinq premières lignes :

# Import packages and set visualization style
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
%matplotlib inline
# Import data and check out head of DataFrame
df = pd.read_csv('data/chasewillden-netflix-shows/data/netflix.csv')
df.head()
  title rating ratinglevel ratingdescription release_year user_rating_score user_rating_size
0 White Chicks PG-13 crude and sexual humor, language and some drug... 80 2004 82.0 80
1 Lucky Number Slevin R strong violence, sexual content and adult lang... 100 2006 NaN 82
2 Grey's Anatomy TV-14 Parents strongly cautioned. May be unsuitable ... 90 2016 98.0 80
3 Prison Break TV-14 Parents strongly cautioned. May be unsuitable ... 90 2008 98.0 80
4 How I Met Your Mother TV-PG Parental guidance suggested. May not be suitab... 70 2014 94.0 80

Plutôt prometteur : vous avez les titres, les classifications, l'année de sortie et la note des utilisateurs, entre autres colonnes. Avant d'exécuter notre groupby et le split-apply-combine, examinons un peu plus finement les données pour valider nos hypothèses et traiter les valeurs manquantes. Notez qu'il y a une valeur manquante (NaN) dans user_rating_score de la deuxième ligne (ligne 1).

Résumer vos données avec graphiques et statistiques

La méthode .info() d'un DataFrame pandas est précieuse. Son application ci-dessous montre que vous avez 1000 lignes et 7 colonnes, mais aussi que la colonne qui nous intéresse, user_rating_score, ne compte que 605 valeurs non nulles. Autrement dit, 395 valeurs manquent :

# Check out info of DataFrame
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 7 columns):
title                1000 non-null object
rating               1000 non-null object
ratinglevel          941 non-null object
ratingdescription    1000 non-null int64
release_year         1000 non-null int64
user_rating_score    605 non-null float64
user_rating_size     1000 non-null int64
dtypes: float64(1), int64(3), object(3)
memory usage: 54.8+ KB

Vous pouvez supprimer les lignes comportant des valeurs manquantes, retirer les doublons et tracer un pairplot du DataFrame avec seaborn pour avoir un aperçu visuel. Nous colorerons les points selon la colonne « rating ». Consultez les graphiques et voyez quelles informations vous en tirez.

# Drop rows with missing values and drop duplicate
df.dropna(inplace=True)
df.drop_duplicates(inplace=True)

# Visualize pairplot of df
sns.pairplot(df, hue='rating');

pairplot seaborn

Regardez, par exemple, user_rating_score en fonction de release_year. On n'observe pas de tendance flagrante à l'œil nu, mais une analyse plus poussée mettra peut-être en évidence un signal. Pour consulter plusieurs statistiques descriptives du DataFrame, utilisez aussi la méthode .describe() :

# Get summary stats of df
df.describe()
  ratingdescription release_year user_rating_score user_rating_size
count 246.000000 246.000000 246.000000 246.0
mean 73.556911 2010.272358 81.390244 80.0
std 26.616145 8.887219 12.677883 0.0
min 10.000000 1940.000000 55.000000 80.0
25% 60.000000 2007.000000 71.000000 80.0
50% 80.000000 2015.000000 83.500000 80.0
75% 90.000000 2016.000000 92.750000 80.0
max 124.000000 2017.000000 99.000000 80.0

Groupby et split-apply-combine pour répondre à la question

Étape 1. Split

Maintenant que vous avez exploré les données, passons au concret. Vous allez d'abord utiliser groupby pour scinder les données en groupes, chaque groupe étant l'ensemble des films sortis une année donnée. C'est la partie split de split-apply-combine :

# Group by year
df_by_year = df.groupby('release_year')

Vous obtenez ainsi un objet groupby :

# Check type of GroupBy object
type(df_by_year)
pandas.core.groupby.DataFrameGroupBy

Étape 2. Apply

Ces objets groupby sont très utiles. Rappelez-vous que la méthode .describe() d'un DataFrame renvoie des statistiques descriptives pour les colonnes numériques ? Eh bien, la méthode .describe() appliquée à un objet DataFrameGroupBy renvoie ces mêmes statistiques pour chaque groupe après la scission. Dans votre cas, c'est pour chaque release_year. C'est un exemple de la partie apply : vous appliquez la méthode .describe() à chaque groupe du groupby. Faites-le et affichez les 5 premières lignes du résultat :

# Summary stats over years
df_by_year.describe().head()
  ratingdescription user_rating_score user_rating_size
  count mean std min 25% 50% 75% max count mean ... 75% max count mean std min 25% 50% 75% max
release_year                                        
1940 1.0 35.0 NaN 35.0 35.0 35.0 35.0 35.0 1.0 61.0 ... 61.0 61.0 1.0 80.0 NaN 80.0 80.0 80.0 80.0 80.0
1978 1.0 60.0 NaN 60.0 60.0 60.0 60.0 60.0 1.0 86.0 ... 86.0 86.0 1.0 80.0 NaN 80.0 80.0 80.0 80.0 80.0
1982 1.0 60.0 NaN 60.0 60.0 60.0 60.0 60.0 1.0 68.0 ... 68.0 68.0 1.0 80.0 NaN 80.0 80.0 80.0 80.0 80.0
1986 1.0 35.0 NaN 35.0 35.0 35.0 35.0 35.0 1.0 67.0 ... 67.0 67.0 1.0 80.0 NaN 80.0 80.0 80.0 80.0 80.0
1987 1.0 60.0 NaN 60.0 60.0 60.0 60.0 60.0 1.0 58.0 ... 58.0 58.0 1.0 80.0 NaN 80.0 80.0 80.0 80.0 80.0

5 rows × 24 columns

Si vous souhaitez visualiser la structure du regroupement, vous pouvez passer l'objet groupby à la fonction list() :

# Cast grouping as a list and check out one year
list(df_by_year)[10]
(1995,             title rating                                ratinglevel  \
 766         Balto      G  General Audiences. Suitable for all ages.   
 967  Heavyweights     PG              some rude language and pranks   

      ratingdescription  release_year  user_rating_score  user_rating_size  
 766                 35          1995               64.0                80  
 967                 60          1995               74.0                80  )

Étape 3. Combine

Supposons que vous vouliez la moyenne ou la médiane de user_rating_score pour chaque année. Vous pouvez alors appliquer respectivement les méthodes .mean() ou .median() à l'objet groupby et « combiner » ces résultats dans un nouveau DataFrame.

# Get median values by year and print first 5 rows
df_med_by_year = df_by_year.median()
df_med_by_year.head()
  ratingdescription user_rating_score user_rating_size
release_year      
1940 35.0 61.0 80.0
1978 60.0 86.0 80.0
1982 60.0 68.0 80.0
1986 35.0 67.0 80.0
1987 60.0 58.0 80.0

Il y a une subtilité importante concernant l'index du DataFrame df_med_by_year. Rappelez-vous que l'index d'un DataFrame correspond aux étiquettes de lignes. Regardez l'index du DataFrame d'origine df :

# Print index of df
print(df.index)
Int64Index([  0,   2,   3,   4,   5,   6,   7,   8,   9,  10,
            ...
            908, 911, 917, 931, 962, 966, 967, 972, 973, 979],
           dtype='int64', length=246)

Cet index correspond aux numéros de lignes d'origine, étiquetés par des entiers. Le « 1 » manque car vous avez supprimé des lignes plus haut. L'index de df_med_by_year, lui, correspond aux valeurs de la colonne d'origine utilisée pour le regroupement, c'est-à-dire les années de release_year :

# Print index
print(df_med_by_year.index)
Int64Index([1940, 1978, 1982, 1986, 1987, 1989, 1990, 1992, 1993, 1994, 1995,
            1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
            2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
           dtype='int64', name='release_year')

Vous vous intéressez à la colonne user_rating_score, qui contient la médiane des notes pour chaque année. Vous pouvez extraire cette colonne de df_med_by_year et la représenter en fonction de l'année (donnée par l'index du DataFrame df_rat_by_year) :

# Slice out user rating and plot
df_rat_by_year = df_med_by_year['user_rating_score']
plt.scatter(df_rat_by_year.index, df_rat_by_year)
plt.xlabel('year of release')
plt.ylabel('median rating');

Netflix groupby split-apply-combine

À la lecture du graphique, la médiane des notes augmente clairement avec le temps. Il faudrait des méthodes statistiques plus poussées pour démontrer la tendance de façon générale, mais c'est un bel exemple où l'analyse exploratoire sert de tremplin à des investigations plus approfondies.

Groupby et split-apply-combine au quotidien

Les objets groupby ne sont pas intuitifs. Ils reflètent toutefois un geste naturel : scinder un jeu de données selon l'une de ses colonnes (ou plusieurs, mais gardons cela pour un autre article sur le regroupement par plusieurs colonnes et les index hiérarchiques).

Le principe split-apply-combine est à la fois élégant et pratique, et il fait partie du quotidien des Data Scientists, comme dans l'exemple ci-dessus. Pour en apprécier toutes les facettes, consultez l'article original de Hadley Wickham ici, The Split-Apply-Combine Strategy for Data Analysis. Si vous avez des idées, réactions et/ou réflexions, n'hésitez pas à me contacter sur Twitter : @hugobowne.

Découvrez d'autres tutoriels pratiques sur pandas de DataCamp, notamment :

Sujets
Python
Science des données

Cours pandas

Cours

Manipulation de données avec pandas

4 h
564K
Apprenez à importer et nettoyer des données, calculer des statistiques et créer des visualisations avec pandas.
Afficher les détailsRight Arrow
Commencer Le Cours
Voir plusRight Arrow