Skip to content
Thèmes
Pandas
Pandas Merge: The Complete Guide to Merging DataFrames in Python

Pandas Merge : Le guide complet pour fusionner des DataFrames en Python

Updated on

Travailler avec un seul DataFrame est rare dans le monde réel. La plupart des projets d'analyse de données nécessitent de combiner des données provenant de plusieurs sources -- des enregistrements de ventes avec des profils de clients, des relevés de capteurs avec des métadonnées d'appareils, ou des réponses à des enquêtes avec des tableaux démographiques. La fonction pandas merge est l'outil standard que les développeurs Python utilisent pour joindre des DataFrames ensemble, et bien la comprendre fait la différence entre passer quelques minutes ou quelques heures sur la préparation des données.

Ce guide couvre tous les aspects de pd.merge() : les quatre types principaux de jointures, la fusion sur plusieurs colonnes, la gestion des noms en double et les pièges courants. Chaque exemple utilise du code fonctionnel que vous pouvez copier directement dans votre notebook.

📚

Ce que fait pd.merge()

pd.merge() combine deux DataFrames en faisant correspondre des lignes en fonction d'une ou plusieurs colonnes partagées (appelées clés). Il fonctionne comme une instruction SQL JOIN. Vous choisissez sur quelles colonnes faire correspondre et quel type de jointure effectuer, et pandas s'occupe du reste.

Voici la syntaxe de base :

import pandas as pd
 
result = pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
                  suffixes=('_x', '_y'), indicator=False, validate=None)

Référence des paramètres clés

ParamètreDescriptionPar défaut
leftLe premier DataFrame (gauche)Requis
rightLe deuxième DataFrame (droit)Requis
howType de jointure : 'inner', 'left', 'right', 'outer', 'cross''inner'
onNom(s) de colonne pour joindre (doivent exister dans les deux DataFrames)None
left_onColonne(s) du DataFrame gauche à utiliser comme clésNone
right_onColonne(s) du DataFrame droit à utiliser comme clésNone
left_indexUtiliser l'index du DataFrame gauche comme clé de jointureFalse
right_indexUtiliser l'index du DataFrame droit comme clé de jointureFalse
suffixesSuffixes à appliquer aux noms de colonnes qui se chevauchent('_x', '_y')
indicatorAjouter une colonne montrant la source de chaque ligneFalse
validateVérifier si la fusion est un-à-un, un-à-plusieurs, etc.None

Si vous omettez on, left_on et right_on, pandas joindra automatiquement toutes les colonnes qui partagent le même nom dans les deux DataFrames.

Données d'exemple pour tous les exemples

Chaque exemple ci-dessous utilise ces deux DataFrames :

import pandas as pd
 
employees = pd.DataFrame({
    'emp_id': [1, 2, 3, 4, 5],
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'dept_id': [10, 20, 10, 30, 20]
})
 
departments = pd.DataFrame({
    'dept_id': [10, 20, 40],
    'dept_name': ['Engineering', 'Marketing', 'Sales']
})
 
print(employees)
print(departments)

Sortie :

   emp_id     name  dept_id
0       1    Alice       10
1       2      Bob       20
2       3  Charlie       10
3       4    Diana       30
4       5      Eve       20

   dept_id    dept_name
0       10  Engineering
1       20    Marketing
2       40        Sales

Notez que dept_id 30 existe uniquement dans employees, et dept_id 40 existe uniquement dans departments. Cette incompatibilité est intentionnelle -- elle rend la différence entre les types de jointures évidente.

Inner Merge (par défaut)

Un inner merge renvoie uniquement les lignes où la clé existe dans les deux DataFrames. Les lignes sans correspondance sont supprimées.

inner_result = pd.merge(employees, departments, on='dept_id', how='inner')
print(inner_result)

Sortie :

   emp_id     name  dept_id    dept_name
0       1    Alice       10  Engineering
1       3  Charlie       10  Engineering
2       2      Bob       20    Marketing
3       5      Eve       20    Marketing

Diana (dept_id=30) est supprimée car le département 30 n'existe pas dans la table departments. Le département 40 (Ventes) est également absent car aucun employé n'en fait partie.

Quand utiliser inner merge : Utilisez-le lorsque vous ne voulez que des enregistrements complets -- des lignes qui ont des données valides des deux côtés. C'est le paramètre par défaut le plus sûr car il n'introduit jamais de valeurs NaN provenant de lignes non appariées.

Left Merge

Un left merge conserve toutes les lignes du DataFrame gauche et uniquement les lignes correspondantes de droite. Là où il n'y a pas de correspondance, les colonnes du côté droit sont remplies avec NaN.

left_result = pd.merge(employees, departments, on='dept_id', how='left')
print(left_result)

Sortie :

   emp_id     name  dept_id    dept_name
0       1    Alice       10  Engineering
1       2      Bob       20    Marketing
2       3  Charlie       10  Engineering
3       4    Diana       30          NaN
4       5      Eve       20    Marketing

Diana est maintenant incluse, mais son dept_name est NaN car le département 30 n'a pas d'entrée dans la table departments.

Quand utiliser left merge : Utilisez-le lorsque le DataFrame gauche est votre ensemble de données "principal" et que vous souhaitez l'enrichir avec des colonnes supplémentaires, sans perdre de lignes de la table principale. C'est le type de merge le plus courant en pratique.

Right Merge

Un right merge est le miroir d'un left merge. Il conserve toutes les lignes du DataFrame droit et uniquement les lignes correspondantes de gauche.

right_result = pd.merge(employees, departments, on='dept_id', how='right')
print(right_result)

Sortie :

   emp_id     name  dept_id    dept_name
0     1.0    Alice       10  Engineering
1     3.0  Charlie       10  Engineering
2     2.0      Bob       20    Marketing
3     5.0      Eve       20    Marketing
4     NaN      NaN       40        Sales

Le département Ventes (dept_id=40) apparaît maintenant même si aucun employé n'en fait partie. Les champs d'employés sont NaN pour cette ligne.

Quand utiliser right merge : En pratique, les right merges sont rares. Vous pouvez toujours réécrire un right merge comme un left merge en échangeant l'ordre des DataFrames. La plupart des bases de code préfèrent les left merges pour la cohérence.

Outer Merge (Full Outer Join)

Un outer merge renvoie toutes les lignes des deux DataFrames. Là où il n'y a pas de correspondance, les valeurs manquantes sont remplies avec NaN.

outer_result = pd.merge(employees, departments, on='dept_id', how='outer')
print(outer_result)

Sortie :

   emp_id     name  dept_id    dept_name
0     1.0    Alice       10  Engineering
1     3.0  Charlie       10  Engineering
2     2.0      Bob       20    Marketing
3     5.0      Eve       20    Marketing
4     4.0    Diana       30          NaN
5     NaN      NaN       40        Sales

Diana (pas de département correspondant) et Ventes (pas d'employés correspondants) apparaissent tous les deux dans le résultat.

Quand utiliser outer merge : Utilisez-le lorsque vous avez besoin d'une image complète des deux ensembles de données et que vous souhaitez identifier quelles lignes n'ont pas correspondu. Le paramètre indicator est particulièrement utile ici.

Comparaison rapide des types de merge

Type de mergeConserve de gaucheConserve de droiteLignes non appariées
innerUniquement appariéesUniquement appariéesSupprimées
leftToutes les lignesUniquement appariéesLignes gauches conservées, droite remplit NaN
rightUniquement appariéesToutes les lignesLignes droites conservées, gauche remplit NaN
outerToutes les lignesToutes les lignesLes deux côtés conservés, NaN où pas de correspondance
crossToutes les lignesToutes les lignesProduit cartésien (toutes les combinaisons)

Fusion sur plusieurs colonnes

Lorsqu'une seule colonne n'est pas suffisante pour identifier de manière unique une correspondance, passez une liste de noms de colonnes à on :

sales = pd.DataFrame({
    'year': [2024, 2024, 2025, 2025],
    'quarter': ['Q1', 'Q2', 'Q1', 'Q2'],
    'revenue': [100, 150, 200, 250]
})
 
targets = pd.DataFrame({
    'year': [2024, 2024, 2025, 2025],
    'quarter': ['Q1', 'Q2', 'Q1', 'Q2'],
    'target': [120, 140, 210, 230]
})
 
merged = pd.merge(sales, targets, on=['year', 'quarter'])
print(merged)

Sortie :

   year quarter  revenue  target
0  2024      Q1      100     120
1  2024      Q2      150     140
2  2025      Q1      200     210
3  2025      Q2      250     230

C'est l'équivalent d'une clé composite en SQL. year et quarter doivent tous les deux correspondre pour que les lignes soient jointes.

Fusion avec des noms de colonnes différents

Parfois, les deux DataFrames utilisent des noms différents pour le même concept. Utilisez left_on et right_on au lieu de on :

orders = pd.DataFrame({
    'order_id': [101, 102, 103],
    'customer_id': [1, 2, 3],
    'amount': [50.0, 75.0, 120.0]
})
 
customers = pd.DataFrame({
    'id': [1, 2, 4],
    'name': ['Alice', 'Bob', 'Diana']
})
 
merged = pd.merge(orders, customers, left_on='customer_id', right_on='id', how='left')
print(merged)

Sortie :

   order_id  customer_id  amount   id   name
0       101            1    50.0  1.0  Alice
1       102            2    75.0  2.0    Bob
2       103            3   120.0  NaN    NaN

Notez que les colonnes customer_id et id apparaissent toutes les deux dans le résultat. Vous pouvez supprimer le doublon après :

merged = merged.drop(columns=['id'])

Gestion des noms de colonnes en double avec des suffixes

Lorsque les deux DataFrames ont des colonnes avec le même nom (en plus de la clé), pandas ajoute des suffixes pour les distinguer :

df1 = pd.DataFrame({
    'id': [1, 2, 3],
    'score': [85, 90, 78]
})
 
df2 = pd.DataFrame({
    'id': [1, 2, 3],
    'score': [88, 92, 80]
})
 
# Suffixes par défaut
merged = pd.merge(df1, df2, on='id')
print(merged)

Sortie :

   id  score_x  score_y
0   1       85       88
1   2       90       92
2   3       78       80

Vous pouvez personnaliser les suffixes pour rendre les noms de colonnes plus significatifs :

merged = pd.merge(df1, df2, on='id', suffixes=('_midterm', '_final'))
print(merged)

Sortie :

   id  score_midterm  score_final
0   1             85           88
1   2             90           92
2   3             78           80

Utilisation du paramètre indicator

Le paramètre indicator ajoute une colonne _merge qui vous indique d'où vient chaque ligne :

result = pd.merge(employees, departments, on='dept_id', how='outer', indicator=True)
print(result)

Sortie :

   emp_id     name  dept_id    dept_name      _merge
0     1.0    Alice       10  Engineering        both
1     3.0  Charlie       10  Engineering        both
2     2.0      Bob       20    Marketing        both
3     5.0      Eve       20    Marketing        both
4     4.0    Diana       30          NaN   left_only
5     NaN      NaN       40        Sales  right_only

C'est extrêmement utile pour les vérifications de qualité des données -- vous pouvez rapidement filtrer les lignes qui n'ont pas correspondu :

unmatched = result[result['_merge'] != 'both']
print(unmatched)

merge() vs join() vs concat() -- Quand utiliser chacun

Pandas offre trois façons de combiner des DataFrames. Voici quand utiliser chacune :

Fonctionnalitépd.merge()df.join()pd.concat()
Type de jointureBasé sur les colonnes (comme SQL)Basé sur l'index par défautEmpiler lignes ou colonnes
Syntaxepd.merge(df1, df2, on='col')df1.join(df2, on='col')pd.concat([df1, df2])
Idéal pourJoindre sur des colonnes partagéesJoindre sur l'indexEmpiler DataFrames verticalement/horizontalement
Plusieurs clésOui (on=['a','b'])LimitéNon applicable
Plusieurs DataFramesDeux à la foisDeux à la foisN'importe quel nombre à la fois
Jointure par défautInnerLeftOuter (axis=0)
FlexibilitéLa plus élevéeMoyenneCas d'usage différent

Règle générale :

  • Utilisez pd.merge() lorsque vous combinez des DataFrames en fonction des valeurs de colonnes (le cas le plus courant).
  • Utilisez df.join() lorsque votre clé de jointure est l'index et que vous voulez une syntaxe plus courte.
  • Utilisez pd.concat() lorsque vous empilez des DataFrames les uns sur les autres (ajout de lignes) ou côte à côte.

Erreurs courantes et dépannage

1. MergeError : les colonnes se chevauchent mais aucun suffixe spécifié

Cela se produit lorsque les deux DataFrames ont des colonnes non-clés avec le même nom et que vous définissez suffixes=(False, False) :

# Correction : utilisez des suffixes significatifs
merged = pd.merge(df1, df2, on='id', suffixes=('_left', '_right'))

2. Explosion de lignes inattendue (fusion plusieurs-à-plusieurs)

Si les deux DataFrames ont des valeurs en double dans la clé de jointure, pandas crée un produit cartésien des lignes correspondantes. Cela peut faire que votre résultat ait beaucoup plus de lignes que l'une ou l'autre entrée :

# Vérifier les doublons avant la fusion
print(df1['key'].duplicated().sum())
print(df2['key'].duplicated().sum())
 
# Utilisez validate pour détecter cela tôt
merged = pd.merge(df1, df2, on='key', validate='one_to_many')

Le paramètre validate accepte 'one_to_one', 'one_to_many', 'many_to_one' et 'many_to_many'. Il lève une MergeError si les données ne correspondent pas à la cardinalité attendue.

3. La colonne clé a des dtypes différents

Si un DataFrame stocke la clé comme int64 et l'autre comme object (chaîne), la fusion échouera ou produira zéro correspondance :

# Vérifier les dtypes
print(df1['id'].dtype)  # int64
print(df2['id'].dtype)  # object
 
# Correction : convertir au même type
df2['id'] = df2['id'].astype(int)
merged = pd.merge(df1, df2, on='id')

4. Valeurs NaN dans les clés

Les lignes avec NaN dans la colonne de clé de jointure ne correspondront à rien (NaN != NaN dans pandas). Supprimez-les ou remplissez-les d'abord :

df1 = df1.dropna(subset=['key'])

Visualisez vos DataFrames fusionnés avec PyGWalker

Après avoir fusionné vos données, l'étape suivante consiste généralement à explorer le résultat -- observer les distributions, repérer les tendances et vérifier les anomalies. Au lieu d'écrire des dizaines d'appels matplotlib ou seaborn, vous pouvez utiliser PyGWalker (opens in a new tab), une bibliothèque Python open source qui transforme n'importe quel DataFrame pandas en une interface d'exploration visuelle interactive de type Tableau directement dans Jupyter Notebook.

import pandas as pd
import pygwalker as pyg
 
# Fusionnez vos DataFrames
employees = pd.DataFrame({
    'emp_id': [1, 2, 3, 4, 5],
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'dept_id': [10, 20, 10, 30, 20],
    'salary': [95000, 82000, 105000, 78000, 91000]
})
 
departments = pd.DataFrame({
    'dept_id': [10, 20, 30],
    'dept_name': ['Engineering', 'Marketing', 'Design']
})
 
merged = pd.merge(employees, departments, on='dept_id')
 
# Lancez la visualisation interactive -- glisser-déposer pour explorer
walker = pyg.walk(merged)

Avec PyGWalker, vous pouvez glisser dept_name vers l'axe x et salary vers l'axe y pour voir instantanément la répartition des salaires par département -- aucun code de graphique nécessaire. Vous pouvez créer des graphiques à barres, des nuages de points, des histogrammes et plus encore simplement en glissant des champs. C'est particulièrement puissant pour explorer les résultats de fusions complexes où vous devez vérifier que la jointure a fonctionné comme prévu.

Vous pouvez essayer PyGWalker dès maintenant dans Google Colab (opens in a new tab), Kaggle (opens in a new tab), ou l'installer avec pip install pygwalker.

FAQ

Quelle est la différence entre pandas merge et join ?

pd.merge() joint des DataFrames en fonction des valeurs de colonnes par défaut et prend en charge tous les types de jointures (inner, left, right, outer, cross). df.join() joint sur l'index par défaut et utilise une jointure gauche. Sous le capot, join() appelle merge(), ils produisent donc les mêmes résultats -- merge() vous donne simplement plus de contrôle sur les colonnes à faire correspondre.

Comment fusionner deux DataFrames sur plusieurs colonnes dans pandas ?

Passez une liste de noms de colonnes au paramètre on : pd.merge(df1, df2, on=['col_a', 'col_b']). Les deux colonnes doivent correspondre pour que les lignes soient jointes. C'est l'équivalent d'une clé composite en SQL.

Pourquoi mon pandas merge crée-t-il des lignes en double ?

Des lignes en double apparaissent lorsque la clé de jointure a des valeurs répétées dans l'un ou les deux DataFrames. Pandas crée un produit cartésien de toutes les lignes correspondantes. Utilisez df.duplicated(subset=['key']).sum() pour vérifier les doublons avant la fusion, ou utilisez validate='one_to_one' pour le détecter tôt.

Qu'est-ce qu'un cross merge dans pandas ?

Un cross merge (how='cross') produit le produit cartésien des deux DataFrames -- chaque ligne de gauche est appariée avec chaque ligne de droite. Si la gauche a 3 lignes et la droite a 4 lignes, le résultat a 12 lignes. C'est utile pour générer toutes les combinaisons possibles, comme apparier chaque produit avec chaque emplacement de magasin.

Comment effectuer un pandas merge sur l'index ?

Définissez left_index=True et/ou right_index=True : pd.merge(df1, df2, left_index=True, right_index=True). Vous pouvez également mélanger les clés d'index et de colonne : pd.merge(df1, df2, left_on='col_a', right_index=True).

Conclusion

La fonction merge() de pandas est l'outil le plus flexible et le plus largement utilisé pour combiner des DataFrames en Python. Pour récapituler les points clés :

  • Inner merge (par défaut) conserve uniquement les lignes qui correspondent dans les deux DataFrames.
  • Left merge conserve toutes les lignes du DataFrame gauche, en remplissant NaN là où la droite n'a pas de correspondance.
  • Right merge conserve toutes les lignes du DataFrame droit -- mais préférez left merge avec ordre échangé pour la cohérence.
  • Outer merge conserve tout des deux côtés, utile pour identifier les enregistrements non appariés avec indicator=True.
  • Utilisez on pour les clés de même nom, left_on/right_on pour les clés de noms différents, et suffixes pour gérer les colonnes qui se chevauchent.
  • Vérifiez toujours les clés en double et les dtypes incompatibles avant la fusion pour éviter les résultats inattendus.

Une fois vos données fusionnées, des outils comme PyGWalker (opens in a new tab) vous permettent d'explorer visuellement le résultat sans écrire de code de graphique, rendant l'ensemble du flux de travail d'analyse plus rapide et plus intuitif.

📚