Nach meinem Verständnis eines linken äußeren Joins sollte die resultierende Tabelle niemals mehr Zeilen als die linke Tabelle enthalten ... Bitte lassen Sie mich wissen, wenn dies falsch ist ...
Meine linke Tabelle besteht aus 192572 Zeilen und 8 Spalten.
Meine rechte Tabelle besteht aus 42160 Zeilen und 5 Spalten.
Meine linke Tabelle enthält ein Feld mit dem Namen "id", das mit einer Spalte in meiner rechten Tabelle mit dem Namen "key" übereinstimmt.
Deshalb füge ich sie als solche zusammen:
combined = pd.merge(a,b,how='left',left_on='id',right_on='key')
Aber dann ist die kombinierte Form 236569.
Was missverstehe ich?
pd.merge
für einen kleinen Abschnitt des Codes verwende, hat die resultierende Tabelle tatsächlich nur die Größe der linken TabelleAntworten:
Sie können davon ausgehen, dass sich dies erhöht, wenn Schlüssel mit mehr als einer Zeile im anderen DataFrame übereinstimmen:
In [11]: df = pd.DataFrame([[1, 3], [2, 4]], columns=['A', 'B']) In [12]: df2 = pd.DataFrame([[1, 5], [1, 6]], columns=['A', 'C']) In [13]: df.merge(df2, how='left') # merges on columns A Out[13]: A B C 0 1 3 5 1 1 3 6 2 2 4 NaN
Um dieses Verhalten zu vermeiden, löschen Sie die Duplikate in df2:
In [21]: df2.drop_duplicates(subset=['A']) # you can use take_last=True Out[21]: A C 0 1 5 In [22]: df.merge(df2.drop_duplicates(subset=['A']), how='left') Out[22]: A B C 0 1 3 5 1 2 4 NaN
quelle
Es gibt auch Strategien, mit denen Sie dieses Verhalten vermeiden können, bei denen die duplizierten Daten nicht verloren gehen, wenn beispielsweise nicht alle Spalten dupliziert werden. Wenn Sie haben
In [1]: df = pd.DataFrame([[1, 3], [2, 4]], columns=['A', 'B']) In [2]: df2 = pd.DataFrame([[1, 5], [1, 6]], columns=['A', 'C'])
Eine Möglichkeit wäre, den Mittelwert des Duplikats zu nehmen (kann auch die Summe usw. nehmen).
In [3]: df3 = df2.groupby('A').mean().reset_index() In [4]: df3 Out[4]: C A 1 5.5 In [5]: merged = pd.merge(df,df3,on=['A'], how='outer') In [6]: merged Out[204]: A B C 0 1 3 5.5 1 2 4 NaN
Wenn Sie nicht numerische Daten haben, die nicht mit pd.to_numeric () konvertiert werden können, oder wenn Sie einfach nicht den Mittelwert nehmen möchten, können Sie die Zusammenführungsvariable ändern, indem Sie die Duplikate auflisten. Diese Strategie würde jedoch angewendet, wenn die Duplikate in beiden Datensätzen vorhanden sind (was das gleiche problematische Verhalten verursachen würde und auch ein häufiges Problem darstellt):
In [7]: df = pd.DataFrame([['a', 3], ['b', 4],['b',0]], columns=['A', 'B']) In [8]: df2 = pd.DataFrame([['a', 3], ['b', 8],['b',5]], columns=['A', 'C']) In [9]: df['count'] = df.groupby('A')['B'].cumcount() In [10]: df['A'] = np.where(df['count']>0,df['A']+df['count'].astype(str),df['A'].astype(str)) In[11]: df Out[11]: A B count 0 a 3 0 1 b 4 0 2 b1 0 1
Machen Sie dasselbe für df2, löschen Sie die Zählvariablen in df und df2 und führen Sie sie auf 'A' zusammen:
In [16]: merged Out[16]: A B C 0 a 3 3 1 b 4 8 2 b1 0 5
Ein paar Notizen. In diesem letzten Fall verwende ich .cumcount () anstelle von .duplicated, da es sein kann, dass Sie für eine bestimmte Beobachtung mehr als ein Duplikat haben. Außerdem verwende ich .astype (str), um die Zählwerte in Zeichenfolgen zu konvertieren, da ich den Befehl np.where () verwende, aber die Verwendung von pd.concat () oder etwas anderem kann unterschiedliche Anwendungen ermöglichen.
Wenn nur ein Datensatz die Duplikate enthält, Sie diese aber dennoch behalten möchten, können Sie die erste Hälfte der letzteren Strategie verwenden, um die Duplikate in der resultierenden Zusammenführung zu unterscheiden.
quelle
Eine kleine Ergänzung zu den gegebenen Antworten ist, dass es einen Parameter namens validate gibt, der verwendet werden kann, um einen Fehler auszulösen, wenn doppelte IDs in der rechten Tabelle übereinstimmen:
combined = pd.merge(a,b,how='left',left_on='id',right_on='key', validate = 'm:1')
quelle