Bonjour ! Dans la leçon précédente, nous avons exploré la puissance de la méthode .groupby() pour résumer et agréger des données au sein d'un unique DataFrame. C'est une compétence fondamentale. Cependant, en analyse de données, il est très rare que toutes les informations dont vous avez besoin se trouvent dans un seul fichier. Plus souvent, les données sont réparties dans plusieurs tables : une pour les clients, une pour les commandes, une autre pour les produits, etc.
L'objectif de cette leçon est de vous apprendre à combiner ces différentes sources de données. Nous allons nous concentrer sur la fonction pd.merge(), qui est l'outil principal de Pandas pour effectuer des opérations de fusion (ou "jointure"), similaires aux JOIN que l'on trouve dans les bases de données SQL. À la fin de cette leçon, vous saurez comment réunir des DataFrames en vous basant sur des colonnes communes pour créer une vue unifiée et complète de vos données.
1. Pourquoi et comment fusionner des données ?
Imaginez que vous travaillez pour une entreprise de commerce en ligne. Vous avez deux fichiers CSV distincts :
- Un fichier
clients.csvavec l'identifiant, le nom et la ville de chaque client. - Un fichier
commandes.csvavec l'identifiant de la commande, l'identifiant du client qui l'a passée et le montant.
Pour analyser les dépenses par ville, vous devez d'abord combiner ces deux ensembles de données. L'opération de fusion vous permet de le faire en reliant les deux tables grâce à une information commune : l'identifiant du client. Cette information commune est appelée la clé de jointure (ou "join key").
La fonction principale pour cela dans Pandas est pd.merge(). Sa syntaxe de base est :pd.merge(left_dataframe, right_dataframe, on='colonne_cle')
L'article suivant d'OpenClassrooms explique très bien ce concept fondamental.
Merge Data Using Pandas - OpenClassrooms
Cet article pose les bases de la fusion de données, en expliquant son utilité et la syntaxe de base de la fonction merge dans Pandas.
Lisez d'abord la section "Understand the Purpose of Merging Data" pour bien saisir le concept de "clé". Ensuite, dans la section "Merge Data Using the merge Function", lisez l'introduction à la fonction et son utilisation avec les arguments on, left_on et right_on.
Comme vous l'avez lu, la clé n'a pas besoin d'avoir le même nom dans les deux DataFrames. Si df1 a une colonne client_id et df2 a une colonne ID_client, vous pouvez les fusionner ainsi :
pd.merge(df1, df2, left_on='client_id', right_on='ID_client')
2. Les quatre types de jointures
Le comportement exact de la fusion dépend du type de jointure que vous spécifiez. Il en existe quatre principaux, que vous choisirez en fonction des informations que vous souhaitez conserver. La manière de les spécifier est via l'argument how.
L'image suivante est un excellent moyen de visualiser ces quatre types de jointures. Pensez au cercle de gauche comme étant votre premier DataFrame (left) et à celui de droite comme étant le second (right). La zone colorée représente les données qui seront conservées après la fusion.

Préparons deux DataFrames simples pour illustrer chaque cas.
import pandas as pd
# DataFrame des employés
df_employes = pd.DataFrame({
'id_employe': [1, 2, 3, 4],
'nom': ['Alice', 'Bob', 'Charlie', 'David'],
'id_dept': [101, 102, 101, 103]
})
# DataFrame des départements
df_departements = pd.DataFrame({
'id_dept': [101, 102, 104],
'nom_dept': ['Ventes', 'Marketing', 'RH']
})
print("Employés:")
print(df_employes)
print("\nDépartements:")
print(df_departements)
Résultat :
Employés:
id_employe nom id_dept
0 1 Alice 101
1 2 Bob 102
2 3 Charlie 101
3 4 David 103
Départements:
id_dept nom_dept
0 101 Ventes
1 102 Marketing
2 104 RH
Remarquez que l'employé David (id_dept 103) est dans un département qui n'est pas listé dans df_departements, et le département RH (id_dept 104) n'a pas d'employés listés dans df_employes.
L'image ci-dessous illustre ce que nous allons obtenir avec chaque type de jointure.

a) Inner Join (Jointure interne)
C'est le type de jointure par défaut. Il ne conserve que les lignes pour lesquelles la clé (id_dept ici) existe dans les deux DataFrames. C'est l'intersection des deux ensembles.
# how='inner' est le comportement par défaut, on peut l'omettre
df_inner = pd.merge(df_employes, df_departements, on='id_dept', how='inner')
print(df_inner)
Résultat :
id_employe nom id_dept nom_dept
0 1 Alice 101 Ventes
1 3 Charlie 101 Ventes
2 2 Bob 102 Marketing
Seuls les employés des départements 101 et 102 sont conservés, car ce sont les seuls ID présents dans les deux tables. David (dept 103) et le département RH (dept 104) sont exclus.
b) Left Join (Jointure à gauche)
Cette jointure conserve toutes les lignes du DataFrame de gauche (df_employes) et ajoute les informations correspondantes du DataFrame de droite. S'il n'y a pas de correspondance pour une ligne de gauche, les colonnes de droite seront remplies avec NaN (Not a Number), la valeur de Pandas pour les données manquantes.
df_left = pd.merge(df_employes, df_departements, on='id_dept', how='left')
print(df_left)
Résultat :
id_employe nom id_dept nom_dept
0 1 Alice 101 Ventes
1 2 Bob 102 Marketing
2 3 Charlie 101 Ventes
3 4 David 103 NaN
Tous les employés sont présents. Comme le département de David (103) n'est pas dans df_departements, nom_dept est NaN.
c) Right Join (Jointure à droite)
C'est l'inverse de la jointure à gauche. Elle conserve toutes les lignes du DataFrame de droite (df_departements) et ajoute les correspondances de gauche.
df_right = pd.merge(df_employes, df_departements, on='id_dept', how='right')
print(df_right)
Résultat :
id_employe nom id_dept nom_dept
0 1.0 Alice 101 Ventes
1 3.0 Charlie 101 Ventes
2 2.0 Bob 102 Marketing
3 NaN NaN 104 RH
Tous les départements sont présents. Comme le département RH (104) n'a pas d'employés dans df_employes, les colonnes id_employe et nom sont NaN.
d) Outer Join (Jointure externe)
Cette jointure conserve toutes les lignes des deux DataFrames. C'est l'union des deux ensembles. Elle remplit avec NaN partout où une correspondance est manquante d'un côté ou de l'autre.
df_outer = pd.merge(df_employes, df_departements, on='id_dept', how='outer')
print(df_outer)
Résultat :
id_employe nom id_dept nom_dept
0 1.0 Alice 101 Ventes
1 3.0 Charlie 101 Ventes
2 2.0 Bob 102 Marketing
3 4.0 David 103 NaN
4 NaN NaN 104 RH
Ici, nous avons à la fois l'employé David (sans nom de département) et le département RH (sans employé). C'est la vue la plus complète, qui ne perd aucune information.
La vidéo suivante, par Alex The Analyst, offre une excellente démonstration visuelle et pratique de ces concepts.
Merging DataFrames in Pandas | Python Pandas Tutorials
Cette vidéo montre clairement comment fonctionnent les différents types de jointures avec des exemples concrets.
Regardez d'abord la visualisation des jointures avec des diagrammes de Venn. Passez à la création des DataFrames d'exemple. Ensuite, comprenez comment fonctionne la jointure inner par défaut. Observez les résultats de la jointure outer, de la jointure left, et enfin de la jointure right.
3. Gérer les colonnes aux noms identiques
Que se passe-t-il si vos deux DataFrames ont des colonnes avec le même nom, mais qui ne sont pas la clé de jointure ? Par exemple, si df_employes et df_departements avaient tous deux une colonne nommée date_creation.
Pandas gère cela automatiquement en ajoutant des suffixes, par défaut _x pour le DataFrame de gauche et _y pour celui de droite. Le résultat contiendrait donc les colonnes date_creation_x et date_creation_y.
Vous pouvez personnaliser ces suffixes avec l'argument suffixes. C'est utile pour rendre vos colonnes plus lisibles.
# Supposons que les deux DFs aient une colonne 'date'
df1_mod = pd.DataFrame({'id': [1,2], 'valeur': [10, 20], 'date': ['2023-01-01', '2023-01-02']})
df2_mod = pd.DataFrame({'id': [1,2], 'autre_valeur': [100, 200], 'date': ['2023-02-15', '2023-02-16']})
df_merged_suffix = pd.merge(
df1_mod,
df2_mod,
on='id',
suffixes=('_employe', '_departement')
)
print(df_merged_suffix)
Résultat :
id valeur date_employe autre_valeur date_departement
0 1 10 2023-01-01 100 2023-02-15
1 2 20 2023-01-02 200 2023-02-16
Les colonnes date ont été renommées en date_employe et date_departement, ce qui est bien plus clair que date_x et date_y.
La vidéo de codebasics ci-dessous aborde également ce point de manière très claire.
Python Pandas Tutorial 9. Merge Dataframes
Cette vidéo explique comment Pandas gère les colonnes dupliquées et comment personnaliser les suffixes.
Regardez le segment qui explique l'argument suffixes pour comprendre comment renommer automatiquement les colonnes qui se chevauchent lors d'une fusion.
Exercice Pratique
Mettons en pratique ces connaissances avec des données de ventes.
import pandas as pd
# Données des produits
df_produits = pd.DataFrame({
'id_produit': [10, 20, 30, 40],
'nom_produit': ['Livre', 'Stylo', 'Cahier', 'Gomme'],
'prix': [15, 1.5, 4, 1]
})
# Données des ventes
df_ventes = pd.DataFrame({
'id_vente': [1001, 1002, 1003, 1004, 1005],
'id_produit': [10, 30, 10, 20, 50], # Note: le produit 50 n'existe pas dans df_produits
'quantite': [2, 5, 1, 10, 3]
})
Vos tâches :
- Fusionnez
df_ventesetdf_produitspour obtenir une table qui contient les détails de chaque vente (nom du produit, quantité, prix). Ne gardez que les ventes pour lesquelles le produit existe dans le catalogue. - Créez un nouveau DataFrame qui liste tous les produits du catalogue (
df_produits), et pour ceux qui ont été vendus, affichez la quantité vendue. Les produits non vendus doivent apparaître avec une quantitéNaN. - Calculez le chiffre d'affaires pour chaque ligne de la table obtenue à la tâche 1 (chiffre d'affaires =
quantite*prix).
Solutions
# 1. Jointure interne pour ne garder que les ventes valides
df_ventes_completes = pd.merge(df_ventes, df_produits, on='id_produit', how='inner')
print("1. Ventes avec détails des produits :")
print(df_ventes_completes)
print("\n" + "="*40 + "\n")
# 2. Jointure à gauche pour lister tous les produits et leurs ventes éventuelles
df_catalogue_ventes = pd.merge(df_produits, df_ventes, on='id_produit', how='left')
print("2. Catalogue complet avec quantités vendues :")
print(df_catalogue_ventes)
print("\n" + "="*40 + "\n")
# 3. Calcul du chiffre d'affaires par vente
df_ventes_completes['chiffre_affaires'] = df_ventes_completes['quantite'] * df_ventes_completes['prix']
print("3. Ventes complètes avec chiffre d'affaires :")
print(df_ventes_completes)
Conclusion
Vous maîtrisez désormais une compétence essentielle pour tout travail sur des données réelles. Savoir combiner des ensembles de données de manière fiable est la porte d'entrée vers des analyses beaucoup plus riches et complexes.
Les points clés à retenir :
- La fusion de DataFrames se fait principalement avec
pd.merge(). - Une clé de jointure (spécifiée avec
on,left_on,right_on) est nécessaire pour relier les tables. - L'argument
howcontrôle le type de jointure et les données conservées :'inner'(par défaut) : conserve uniquement les correspondances.'left': conserve tout le DataFrame de gauche.'right': conserve tout le DataFrame de droite.'outer': conserve tout de ambos les DataFrames.
- Pandas gère les colonnes non-clés du même nom en ajoutant des suffixes, que vous pouvez personnaliser avec l'argument
suffixes.
Maintenant que nous savons préparer nos données en les nettoyant, en les groupant et en les fusionnant, il est temps de passer à l'étape suivante de l'analyse : la visualisation. Dans la prochaine leçon, nous apprendrons à créer des graphiques de base (lignes, barres, histogrammes) avec la bibliothèque Matplotlib pour transformer nos tables de chiffres en informations visuelles et intuitives.