2014-04-25 15 views
6

Die Operation, die ich machen möchte, ist ähnlich wie eine Fusion. Zum Beispiel erhalten wir mit der inner Fusion einen Datenrahmen, der Zeilen enthält, die im ersten UND zweiten Datenrahmen vorhanden sind. Mit der outer Fusion erhalten wir einen Datenrahmen, der ENTWEDER im ersten ODER im zweiten Datenrahmen vorhanden ist.Wie subtrahiert man Reihen eines Pandas-Datenrahmens von einem anderen?

Was ich brauche, ist ein Datenrahmen, der Zeilen enthält, die im ersten Datenrahmen vorhanden sind UND NICHT in der zweiten vorhanden sind? Gibt es einen schnellen und eleganten Weg, es zu tun?

+0

how = 'links'? sicherlich ist das nicht, was Sie wollen (angesichts Ihrer SO-Note muss es komplexer sein) –

+0

Links oder rechts merge gibt mir einen Datenrahmen, der Zeilen enthält, die in einem der Datenrahmen vorhanden sind. Aber ich brauche einen Datenrahmen, der Zeilen enthält, die in einem Datenrahmen und NICHT in einem anderen vorhanden sind. – Roman

+0

Wenn es nur eine Zusammenführungsschlüssel ist, dann könntest du es mit 'isin' und' ~ ' –

Antwort

6

Wie wäre es mit etwas wie dem Folgenden?

print df1 

    Team Year foo 
0 Hawks 2001 5 
1 Hawks 2004 4 
2 Nets 1987 3 
3 Nets 1988 6 
4 Nets 2001 8 
5 Nets 2000 10 
6 Heat 2004 6 
7 Pacers 2003 12 

print df2 

    Team Year foo 
0 Pacers 2003 12 
1 Heat 2004 6 
2 Nets 1988 6 

Solange es ein nicht-Schlüssel ist in der Regel Spalte mit dem Namen, können Sie die hinzugefügte auf sufffexes die Arbeit machen lassen (wenn es keine nicht-Schlüssel gemeinsame Spalte dann könnte man eine erstellen vorübergehend zu verwenden .. . df1['common'] = 1 und df2['common'] = 1):

new = df1.merge(df2,on=['Team','Year'],how='left') 
print new[new.foo_y.isnull()] 

    Team Year foo_x foo_y 
0 Hawks 2001  5 NaN 
1 Hawks 2004  4 NaN 
2 Nets 1987  3 NaN 
4 Nets 2001  8 NaN 
5 Nets 2000  10 NaN 

Oder können Sie isin aber Sie würden einen einzigen Schlüssel erstellen haben verwenden:

df1['key'] = df1['Team'] + df1['Year'].astype(str) 
df2['key'] = df1['Team'] + df2['Year'].astype(str) 
print df1[~df1.key.isin(df2.key)] 

    Team Year foo   key 
0 Hawks 2001 5 Hawks2001 
2 Nets 1987 3 Nets1987 
4 Nets 2001 8 Nets2001 
5 Nets 2000 10 Nets2000 
6 Heat 2004 6 Heat2004 
7 Pacers 2003 12 Pacers2003 
4

Sie in e laufen konnte Rrors, wenn Ihre Nicht-Index-Spalte Zellen mit NaN hat.

print df1 

    Team Year foo 
0 Hawks 2001 5 
1 Hawks 2004 4 
2 Nets 1987 3 
3 Nets 1988 6 
4 Nets 2001 8 
5 Nets 2000 10 
6 Heat 2004 6 
7 Pacers 2003 12 
8 Problem 2112 NaN 


print df2 

    Team Year foo 
0 Pacers 2003 12 
1 Heat 2004 6 
2 Nets 1988 6 
3 Problem 2112 NaN 

new = df1.merge(df2,on=['Team','Year'],how='left') 
print new[new.foo_y.isnull()] 

    Team Year foo_x foo_y 
0 Hawks 2001  5 NaN 
1 Hawks 2004  4 NaN 
2 Nets 1987  3 NaN 
4 Nets 2001  8 NaN 
5 Nets 2000  10 NaN 
6 Problem 2112 NaN NaN 

Das Problem Team in 2112 hat keinen Wert für foo in beiden Tabellen. Der linke Join hier wird die Zeile, die in beiden Datenrahmen übereinstimmt, fälschlicherweise als nicht im rechten Datenrahmen vorhanden zurückgeben.

Lösung:

Was ich tue, ist eine einzigartige Spalte auf den inneren Datenrahmen hinzufügen und einen Wert für alle Zeilen eingestellt. Wenn Sie dann beitreten, können Sie überprüfen, ob diese Spalte NaN ist, damit die innere Tabelle eindeutige Datensätze in der äußeren Tabelle findet.

df2['in_df2']='yes' 

print df2 

    Team Year foo in_df2 
0 Pacers 2003 12  yes 
1 Heat 2004 6  yes 
2 Nets 1988 6  yes 
3 Problem 2112 NaN  yes 


new = df1.merge(df2,on=['Team','Year'],how='left') 
print new[new.in_df2.isnull()] 

    Team Year foo_x foo_y in_df1 in_df2 
0 Hawks 2001  5 NaN  yes  NaN 
1 Hawks 2004  4 NaN  yes  NaN 
2 Nets 1987  3 NaN  yes  NaN 
4 Nets 2001  8 NaN  yes  NaN 
5 Nets 2000  10 NaN  yes  NaN 

NB. Die Problemzeile wird jetzt korrekt herausgefiltert, da sie einen Wert für in_df2 enthält. Nach

Problem 2112 NaN NaN  yes  yes 
+0

Ausgezeichnet, das hat gut für mich funktioniert. – Dirk

3

Bedenken Sie:

  1. df_one erster Datenrahmen ist
  2. df_two zweiter Datenrahmen ist

Präsens in Ersten Datenrahmen und Nicht in der zweiten Datenrahmen

Lösung: von Index df = df_one[~df_one.index.isin(df_two.index)]

Index kann durch erforderliche Säule ersetzt werden, auf dem Sie möchten Ausschluss tun. Im obigen Beispiel habe ich Index als Referenz zwischen beiden Datenrahmen verwendet

Zusätzlich können Sie auch eine komplexere Abfrage mit Boolean Pandas verwenden.Serie für oben zu lösen.

Verwandte Themen