Ich habe zwei Pandas-Datenrahmen, die einige Zeilen gemeinsam haben.
Angenommen, Datenrahmen2 ist eine Teilmenge von Datenrahmen1.
Wie kann ich die Zeilen von Datenrahmen1 abrufen, die sich nicht in Datenrahmen2 befinden?
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 'col2' : [10, 11, 12, 13, 14]})
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]})
Antworten:
Eine Methode wäre, das Ergebnis einer inneren Zusammenführung aus beiden dfs zu speichern. Dann können wir einfach die Zeilen auswählen, wenn die Werte einer Spalte nicht so häufig sind:
BEARBEITEN
Eine andere Methode, die Sie gefunden haben, besteht darin
isin
,NaN
Zeilen zu erstellen, die Sie löschen können:Wenn df2 Zeilen jedoch nicht auf die gleiche Weise startet, funktioniert dies nicht:
wird das gesamte df produzieren:
quelle
df1[~df1.isin(df2)].dropna(how = 'all')
scheint den Trick zu tun. Trotzdem danke - Ihre Antwort hat mir geholfen, eine Lösung zu finden.isin
beide dfs mit denselben Zeilenwerten beginnen müssen. Wenn also beispielsweise df2 war, funktioniertdf2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11,12, 13]})
Ihre Methode nicht4 | 13
zum4.0 | 13.0
Beispiel von bis . Dies geschah nach diesem Schritt:df1[~df1.isin(df2)].dropna()
Die aktuell ausgewählte Lösung führt zu falschen Ergebnissen. Um dieses Problem richtig zu lösen, können wir eine Linksverknüpfung von
df1
bis durchführendf2
und sicherstellen, dass zuerst nur die eindeutigen Zeilen für abgerufen werdendf2
.Zuerst müssen wir den ursprünglichen DataFrame ändern, um die Zeile mit Daten hinzuzufügen [3, 10].
Führen Sie eine Linksverknüpfung durch, wobei Sie Duplikate entfernen,
df2
sodass jede Verknüpfungsreihedf1
genau 1 Zeile enthältdf2
. Verwenden Sie den Parameterindicator
, um eine zusätzliche Spalte zurückzugeben, die angibt, aus welcher Tabelle die Zeile stammt.Erstellen Sie eine boolesche Bedingung:
Warum andere Lösungen falsch sind
Einige Lösungen machen den gleichen Fehler - sie prüfen nur, ob jeder Wert in jeder Spalte unabhängig ist und nicht zusammen in derselben Zeile. Das Hinzufügen der letzten Zeile, die eindeutig ist, aber die Werte aus beiden Spalten enthält,
df2
macht den Fehler sichtbar:Diese Lösung führt zum gleichen falschen Ergebnis:
quelle
df_all[df_all['_merge'] == 'left_only']
, um eine df mit den Ergebnissen zu habenAngenommen, die Indizes sind in den Datenrahmen konsistent (ohne Berücksichtigung der tatsächlichen Spaltenwerte):
quelle
df1
denen sich die Indizes NICHT befindendf2.index
". Weitere Informationen zur Negation: stackoverflow.com/q/19960077/304209 (überraschenderweise konnte ich in Pandas-Dokumenten keine Erwähnungen von Tilde finden).ValueError: Item wrong length x instead of y.
Wie bereits angedeutet, erfordert isin, dass Spalten und Indizes für eine Übereinstimmung identisch sind. Wenn die Übereinstimmung nur für den Zeileninhalt gelten soll, besteht eine Möglichkeit, die Maske zum Filtern der vorhandenen Zeilen zu erhalten, darin, die Zeilen in einen (Mehrfach-) Index zu konvertieren:
Wenn der Index berücksichtigt werden soll, wird bei set_index das Schlüsselwortargument angehängt, um Spalten an den vorhandenen Index anzuhängen. Wenn die Spalten nicht ausgerichtet sind, kann die Liste (df.columns) durch Spaltenspezifikationen ersetzt werden, um die Daten auszurichten.
könnte alternativ verwendet werden, um die Indizes zu erstellen, obwohl ich bezweifle, dass dies effizienter ist.
quelle
Angenommen, Sie haben zwei Datenrahmen, df_1 und df_2 mit mehreren Feldern (Spaltennamen), und Sie möchten anhand einiger Felder (z. B. Felder_x, Felder_y) die einzigen Einträge in df_1 finden, die nicht in df_2 enthalten sind. Führen Sie die folgenden Schritte aus.
Schritt 1. Fügen Sie df_1 bzw. df_2 eine Spalte key1 und key2 hinzu.
Schritt 2. Führen Sie die Datenrahmen wie unten gezeigt zusammen. field_x und field_y sind unsere gewünschten Spalten.
Schritt 3.Wählen Sie nur die Zeilen aus df_1 aus, in denen Schlüssel1 nicht gleich Schlüssel2 ist.
Step4.Drop key1 und key2.
Diese Methode löst Ihr Problem und funktioniert auch bei großen Datenmengen schnell. Ich habe es für Datenrahmen mit mehr als 1.000.000 Zeilen versucht.
quelle
etwas spät, aber es könnte sich lohnen, den "Indikator" -Parameter von pd.merge zu überprüfen.
In dieser anderen Frage finden Sie ein Beispiel: Vergleichen Sie PandaS DataFrames und geben Sie Zeilen zurück, die in der ersten fehlen
quelle
Sie können dies mit der isin (dict) -Methode tun :
Erläuterung:
quelle
Sie können auch verketten
df1
,df2
:und entfernen Sie dann alle Duplikate:
quelle
Wie wäre es damit:
quelle
Hier ist eine andere Möglichkeit, dies zu lösen:
Oder:
quelle
Um dies zu tun, füge ich eine neue Spalte hinzu, die für einen Datenrahmen eindeutig ist, und wähle anhand dieser Spalte aus, ob ein Eintrag beibehalten werden soll
Dadurch hat jeder Eintrag in df1 einen Code - 0, wenn er für df1 eindeutig ist, 1, wenn er in beiden dataFrames enthalten ist. Sie verwenden dies dann, um sich auf das zu beschränken, was Sie möchten
quelle
quelle