Skip to content

Pandas Merge & Join: SQL-ähnliche Joins richtig machen

Updated on

Joins sind fehleranfällig: falsche Keys, doppelte Zeilen oder stilles Datenverlust. how="inner" wird oft überstrapaziert, validate und indicator fehlen häufig.

PAS-Ansatz:

  • Problem: Joins vervielfachen Zeilen oder verlieren Datensätze wegen unpassender Schlüssel.
  • Agitation: Debugging kostet Zeit—überlappende Spalten, unerwartete Kartesierprodukte oder fehlende Zeilen.
  • Lösung: Schlüssel explizit setzen, validate nutzen, den passenden how wählen und indicator für einen schnellen Audit hinzufügen.

Join-Cheat-Sheet

Join-Typ (how)Behält links?Behält rechts?Typischer Einsatz
inner✅ nur Matches✅ nur MatchesSchnittmenge
left✅ alle🚫 nur MatchesLinke Tabelle anreichern
right🚫 nur Matches✅ alleRechte Tabelle anreichern (selten; meist besser tauschen)
outer✅ alle✅ alleVollständige Vereinigung mit Lücken

Beispieldaten

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"],
})

Standard-Merge auf Spaltenschlüssel

result = orders.merge(
    customers,
    on="customer_id",
    how="left",
    validate="many_to_one",  # Dimensionstabelle erwartet
    indicator=True,          # Join-Abdeckung prüfen
)
  • validate fängt unerwartete Kardinalitäten ab (many_to_many ernst nehmen).
  • indicator zeigt _merge mit left_only/right_only/both.
  • suffixes=("_order", "_cust") verhindert überschreibende Spaltennamen.

Join mit unterschiedlichen Spaltennamen

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",
)

Index-basierte Joins

customers_idx = customers.set_index("customer_id")
orders.join(customers_idx, on="customer_id", how="left")
  • .join ist praktisch, wenn die rechte Tabelle im Index keyed ist.
  • Bei Multi-Index: on=["level_0", "level_1"] oder vorher angleichen.

Duplikate und Überschneidungen handhaben

# Dubletten vor dem Merge finden
dupes = customers["customer_id"].value_counts()
problem_keys = dupes[dupes > 1]
 
# Nach dem Merge unerwünschte Explosionen erkennen
exploded = orders.merge(customers, on="customer_id", how="inner", validate="many_to_many")
  • Steigt die Zeilenzahl bei erwartetem many_to_one, sind Duplikate zu prüfen.
  • drop_duplicates(subset=keys) auf der Dimensionstabelle hilft oft.

Mehrere Metriken auf einmal mergen

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")

Aggregation + Merge reduziert Kaskaden von Joins auf Rohdaten.


Debug-Checkliste

SymptomPrüfung
Zeilenzahl explodiert_merge prüfen, validate auf erwartete Kardinalität setzen.
Fehlende Zeilen nach Mergehow="left" oder how="outer" testen; Key-Datentypen angleichen.
Falsche MatchesSicherstellen, dass Join-Keys denselben Datentyp haben.
Überlappende Spaltennamensuffixes explizit setzen, Überschreiben vermeiden.

Verwandte Guides


Wichtigste Punkte

  • Join-Typ bewusst wählen; left ist meist am sichersten zum Anreichern.
  • validate, indicator und suffixes früh setzen, um Probleme zu sehen.
  • Keys und Datentypen ausrichten; Dimensionstabellen deduplizieren, um Explosionen zu vermeiden.