Pandas Merge & Join : des joins SQL maîtrisés
Updated on
Les joins sont piégeux : clés mal alignées, lignes dupliquées ou perte silencieuse de données. how="inner" est souvent sur-utilisé et validate/indicator oubliés.
Cadre PAS :
- Problème : Les merges multiplient les lignes ou en suppriment à cause de clés incorrectes.
- Agiter : Déboguer les joins prend du temps—sufixes doublonnés, produits cartésiens inattendus, lignes manquantes.
- Solution : Définir les clés explicitement, choisir le bon
how, utiliservalidateet ajouterindicatorpour auditer rapidement.
Tableau mémo des joins
Type (how) | Garde la gauche ? | Garde la droite ? | Usage typique |
|---|---|---|---|
inner | ✅ seulement les matches | ✅ seulement les matches | Intersection |
left | ✅ tout | 🚫 seulement matches | Enrichir la table de gauche |
right | 🚫 seulement matches | ✅ tout | Enrichir la droite (rare, mieux inverser) |
outer | ✅ tout | ✅ tout | Union complète avec trous |
Données d’exemple
import pandas as pd
orders = pd.DataFrame({
"order_id": [1, 2, 3],
"customer_id": [100, 101, 102],
"amount": [50, 80, 60],
})
customers = pd.DataFrame({
"customer_id": [100, 101, 103],
"name": ["Ada", "Ben", "Cara"],
"segment": ["pro", "basic", "pro"],
})Merge de base sur une clé de colonne
result = orders.merge(
customers,
on="customer_id",
how="left",
validate="many_to_one", # table dimension attendue
indicator=True, # audit de couverture
)validatesignale les cardinalités inattendues (many_to_manyest un vrai warning).indicatorajoute_mergeavecleft_only/right_only/both.suffixes=("_order", "_cust")évite d’écraser des colonnes.
Join avec clés de noms différents
payments = pd.DataFrame({
"cust_id": [100, 100, 103],
"last_payment": ["2025-05-20", "2025-05-27", "2025-05-21"],
})
orders.merge(
payments,
left_on="customer_id",
right_on="cust_id",
how="left",
)Joins basés sur l’index
customers_idx = customers.set_index("customer_id")
orders.join(customers_idx, on="customer_id", how="left").joinest pratique quand la table droite a la clé en index.- Pour un multi-index, utilisez
on=["level_0", "level_1"]ou alignez les index avant.
Gérer doublons et chevauchements
# Détecter les clés dupliquées avant le merge
dupes = customers["customer_id"].value_counts()
problem_keys = dupes[dupes > 1]
# Après merge, repérer les explosions
exploded = orders.merge(customers, on="customer_id", how="inner", validate="many_to_many")- Si le nombre de lignes monte alors qu’on attendait
many_to_one, vérifier les doublons. drop_duplicates(subset=keys)sur la table de dimensions aide souvent.
Fusionner plusieurs métriques d’un coup
agg = (
orders.groupby("customer_id", as_index=False)
.agg(total_amount=("amount", "sum"), orders_count=("order_id", "count"))
)
customers.merge(agg, on="customer_id", how="left")Agrégation + merge réduit les chaînes de joins sur des données transactionnelles brutes.
Checklist de débogage
| Symptôme | Vérification |
|---|---|
| Le nombre de lignes explose | Inspecter _merge; régler validate sur la cardinalité attendue. |
| Lignes manquantes après merge | Tester how="left" ou how="outer"; aligner les dtypes des clés. |
| Mauvaises correspondances | S’assurer que les clés ont le même dtype (str vs int, etc.). |
| Colonnes qui se chevauchent | Définir suffixes pour éviter les écrasements. |
Guides liés
Points clés
- Choisir le type de join avec intention;
leftest le plus sûr pour enrichir. validate,indicatoretsuffixesdétectent tôt les problèmes.- Aligner clés et dtypes; dédupliquer les tables de dimensions pour éviter les explosions.