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ètre | Description | Par défaut |
|---|---|---|
left | Le premier DataFrame (gauche) | Requis |
right | Le deuxième DataFrame (droit) | Requis |
how | Type de jointure : 'inner', 'left', 'right', 'outer', 'cross' | 'inner' |
on | Nom(s) de colonne pour joindre (doivent exister dans les deux DataFrames) | None |
left_on | Colonne(s) du DataFrame gauche à utiliser comme clés | None |
right_on | Colonne(s) du DataFrame droit à utiliser comme clés | None |
left_index | Utiliser l'index du DataFrame gauche comme clé de jointure | False |
right_index | Utiliser l'index du DataFrame droit comme clé de jointure | False |
suffixes | Suffixes à appliquer aux noms de colonnes qui se chevauchent | ('_x', '_y') |
indicator | Ajouter une colonne montrant la source de chaque ligne | False |
validate | Vé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 SalesNotez 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 MarketingDiana (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 MarketingDiana 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 SalesLe 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 SalesDiana (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 merge | Conserve de gauche | Conserve de droite | Lignes non appariées |
|---|---|---|---|
inner | Uniquement appariées | Uniquement appariées | Supprimées |
left | Toutes les lignes | Uniquement appariées | Lignes gauches conservées, droite remplit NaN |
right | Uniquement appariées | Toutes les lignes | Lignes droites conservées, gauche remplit NaN |
outer | Toutes les lignes | Toutes les lignes | Les deux côtés conservés, NaN où pas de correspondance |
cross | Toutes les lignes | Toutes les lignes | Produit 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 230C'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 NaNNotez 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 80Vous 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 80Utilisation 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_onlyC'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 jointure | Basé sur les colonnes (comme SQL) | Basé sur l'index par défaut | Empiler lignes ou colonnes |
| Syntaxe | pd.merge(df1, df2, on='col') | df1.join(df2, on='col') | pd.concat([df1, df2]) |
| Idéal pour | Joindre sur des colonnes partagées | Joindre sur l'index | Empiler DataFrames verticalement/horizontalement |
| Plusieurs clés | Oui (on=['a','b']) | Limité | Non applicable |
| Plusieurs DataFrames | Deux à la fois | Deux à la fois | N'importe quel nombre à la fois |
| Jointure par défaut | Inner | Left | Outer (axis=0) |
| Flexibilité | La plus élevée | Moyenne | Cas 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
onpour les clés de même nom,left_on/right_onpour les clés de noms différents, etsuffixespour 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.