Kombinieren und Zusammenführen von Datensätzen¶
Die in pandas-Objekten enthaltenen Daten können auf verschiedene Weise miteinander kombiniert werden:
pandas.merge verbindet Zeilen in DataFrames basierend auf einem oder mehreren Schlüsseln. Diese Funktion ist von SQL oder anderen relationalen Datenbanken vertraut, da sie Datenbank-Join-Operationen implementiert.
pandas.concat verkettet oder stapelt Objekte entlang einer Achse.
Die Instanzmethoden pandas.DataFrame.combine_first oder pandas.Series.combine_first ermöglichen das Zusammenfügen von sich überschneidenden Daten, um fehlende Werte in einem Objekt mit Werten aus einem anderen zu ergänzen.
Mit pandas.merge_asof könnt ihr zeitreihenbasierte Window Joins zwischen DataFrame-Objekten durchführen.
Datenbankähnliche DataFrame-Joins¶
Merge- oder Join-Operationen kombinieren Datensätze durch die Verknüpfung von Zeilen mit einem oder mehreren Schlüsseln. Diese Operationen sind besonders wichtig in relationalen, SQL-basierten Datenbanken. Die Merge-Funktion in pandas ist der Haupteinstiegspunkt für die Anwendung dieser Algorithmen auf eure Daten.
[1]:
import pandas as pd
[2]:
books = pd.DataFrame(
{"Language": ["en", "en", "de", "fr", "de", "de", "en"], "Range": range(7)}
)
updates = pd.DataFrame({"Language": ["de", "en", "pt"], "Range": range(3)})
[3]:
books
[3]:
Language | Range | |
---|---|---|
0 | en | 0 |
1 | en | 1 |
2 | de | 2 |
3 | fr | 3 |
4 | de | 4 |
5 | de | 5 |
6 | en | 6 |
[4]:
updates
[4]:
Language | Range | |
---|---|---|
0 | de | 0 |
1 | en | 1 |
2 | pt | 2 |
Dies ist ein Beispiel für eine 1:n-Beziehung; die Daten in df1
haben mehrere Zeilen mit den Bezeichnungen de
und en
, während df2
nur eine Zeile für jeden Wert in der Schlüsselspalte hat. Wenn wir merge
mit diesen Objekten aufrufen, erhalten wir:
[5]:
pd.merge(books, updates)
[5]:
Language | Range | |
---|---|---|
0 | en | 1 |
Hinweis:
Beachtet, dass ich nicht angegeben habe, über welche Spalte die Verknüpfung erfolgen soll. Wenn diese Information nicht angegeben wird, verwendet merge
die sich überschneidenden Spaltennamen als Schlüssel. Es ist jedoch eine gute Praxis, dies explizit anzugeben:
[6]:
pd.merge(books, updates, on="Language")
[6]:
Language | Range_x | Range_y | |
---|---|---|---|
0 | en | 0 | 1 |
1 | en | 1 | 1 |
2 | de | 2 | 0 |
3 | de | 4 | 0 |
4 | de | 5 | 0 |
5 | en | 6 | 1 |
Wenn die Spaltennamen in jedem Objekt unterschiedlich sind, könnt ihr sie separat angeben:
[7]:
books = pd.DataFrame(
{"Language": ["en", "en", "de", "fr", "de", "de", "en"], "Range": range(7)}
)
updates = pd.DataFrame({"Language": ["de", "en", "es"], "Range": range(3)})
pd.merge(books, updates, left_on="Language", right_on="Language")
[7]:
Language | Range_x | Range_y | |
---|---|---|---|
0 | en | 0 | 1 |
1 | en | 1 | 1 |
2 | de | 2 | 0 |
3 | de | 4 | 0 |
4 | de | 5 | 0 |
5 | en | 6 | 1 |
Fie Werte fr
und es
und die zugehörigen Daten fehlen im Ergebnis. Standardmäßig führt merge
einen Inner Join durch; die Schlüssel im Ergebnis sind die Schnittmenge bzw. die gemeinsame Menge in beiden Tabellen. Andere mögliche Optionen sind Left Join, Right Join und Outer Join. Outer Join nimmt die Vereinigung der Schlüssel und kombiniert den Effekt der Anwendung von Left Join und Right Join:
[8]:
pd.merge(books, updates, how="outer")
[8]:
Language | Range | |
---|---|---|
0 | de | 0 |
1 | de | 2 |
2 | de | 4 |
3 | de | 5 |
4 | en | 0 |
5 | en | 1 |
6 | en | 6 |
7 | es | 2 |
8 | fr | 3 |
Verschiedene Join-Typen mit how
-Argument
Option |
Verhalten |
---|---|
|
verwendet nur die in beiden Tabellen beobachteten Schlüsselkombinationen |
|
verwendet alle in der linken Tabelle gefundenen Schlüsselkombinationen |
|
verwendet alle in der rechten Tabelle gefundenen Schlüsselkombinationen |
|
verwendet alle in beiden Tabellen beobachteten Schlüsselkombinationen zusammen |
n:n-Beziehungen bilden das kartesische Produkt der übereinstimmenden Schlüssel, z.B.:
[9]:
pd.merge(books, updates, on="Language", how="left")
[9]:
Language | Range_x | Range_y | |
---|---|---|---|
0 | en | 0 | 1.0 |
1 | en | 1 | 1.0 |
2 | de | 2 | 0.0 |
3 | fr | 3 | NaN |
4 | de | 4 | 0.0 |
5 | de | 5 | 0.0 |
6 | en | 6 | 1.0 |
Da es drei en
-Zeilen im linken DataFrame und einen im rechten DataFrame gab, gibt es drei en
-Zeilen im Ergebnis. Die Join-Methode wirkt sich nur auf die eindeutigen Schlüsselwerte aus, die im Ergebnis erscheinen:
Um mehrere Schlüssel zusammenzuführen, übergebt eine Liste von Spaltennamen:
[10]:
books = pd.DataFrame(
{
"Title": ["Jupyter Tutorial", "Jupyter Tutorial", "PyViz Tutorial"],
"Language": ["de", "en", "de"],
"Range": [1, 2, 3],
}
)
updates = pd.DataFrame(
{
"Title": [
"Jupyter Tutorial",
"PyViz Tutorial",
"Python Basics",
"Python Basics",
],
"Language": ["de", "de", "de", "en"],
"Range": [4, 5, 6, 7],
}
)
pd.merge(books, updates, on=["Title", "Language"], how="outer")
[10]:
Title | Language | Range_x | Range_y | |
---|---|---|---|---|
0 | Jupyter Tutorial | de | 1.0 | 4.0 |
1 | Jupyter Tutorial | en | 2.0 | NaN |
2 | PyViz Tutorial | de | 3.0 | 5.0 |
3 | Python Basics | de | NaN | 6.0 |
4 | Python Basics | en | NaN | 7.0 |