Vergleichen von DataFrames

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Hatsi09
User
Beiträge: 3
Registriert: Montag 31. Mai 2021, 16:55

Hallo Leute,

ich bin ein blutiger Pythonanfänger. Ich habe 2 pandas DataFrames aus .csv-Dateien ausgelesen. Diese schauen wie folgt aus (zum reproduzieren):

Code: Alles auswählen

df1 = pd.DataFrame([['Hans', -10, 10], ['Jürgen', 0, 45], ['Johanna', -3, 0], ['Marlene', 5, 50], ['Iris', 5, 34], ['Florian', 7, 40], ['Tommy', -4, 68]], columns=['Name', 'Abweichung', 'altePunktzahl'])
df2 = pd.DataFrame([['Hans', 20], ['Jürgen', 45], ['Johanna', 3], ['Marlene', 45]], columns=['Name', 'Punktzahl'])
Ich möchte nun alle Datensätze aus df1 löschen, deren Namen auch in df2 vorkommen. Hat jemand ne Idee, wie ich das am besten mache?
Benutzeravatar
__blackjack__
User
Beiträge: 12984
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Code: Alles auswählen

In [34]: df1["Name"]  # Namen von `df1`.
Out[34]: 
0       Hans
1     Jürgen
2    Johanna
3    Marlene
4       Iris
5    Florian
6      Tommy
Name: Name, dtype: object

In [35]: df1["Name"].isin(df2["Name"])  # Ist der Name von `df1` in `df2` enthalten?
Out[35]: 
0     True
1     True
2     True
3     True
4    False
5    False
6    False
Name: Name, dtype: bool

In [36]: ~df1["Name"].isin(df2["Name"])  # Ist der Name *nicht* enthalten?
Out[36]: 
0    False
1    False
2    False
3    False
4     True
5     True
6     True
Name: Name, dtype: bool

In [37]: df1[~df1["Name"].isin(df2["Name"])]  # Die nicht in `df2` enthaltenen Namen selektieren.
Out[37]: 
      Name  Abweichung  altePunktzahl
4     Iris           5             34
5  Florian           7             40
6    Tommy          -4             68
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Hatsi09
User
Beiträge: 3
Registriert: Montag 31. Mai 2021, 16:55

viele Dank, soweit funktioniert es. Ich habe versucht, da mehrere Bedingung zu verknüpfen, allerdings scheint das nicht zu funktionieren.
kann ich folgendes machen, wenn ich nur die entfernen will, die in df2 stehen und deren ABweichung < 0 ist:

Code: Alles auswählen

df1[~df1["Name"].isin(df2["Name"]) & df1["Abweichung"] < 0]
irgendwie scheint dies nicht das gewünschte Resultat zu liefern
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

& hat eine höhere Priorität als <, daher mußt Du klammern:

Code: Alles auswählen

~df1["Name"].isin(df2["Name"]) & (df1["Abweichung"] < 0)
Hatsi09
User
Beiträge: 3
Registriert: Montag 31. Mai 2021, 16:55

ok danke für den Hinweis, leider liefert es nicht das gewünschte Ergebnis:

Code: Alles auswählen

In [7]: df1
Out [7]: 
      Name  Abweichung  altePunktzahl
0     Hans         -10             10
1   Jürgen           0             45
2  Johanna          -3              0
3  Marlene           5             50
4     Iris           5             34
5  Florian           7             40
6    Tommy          -4             68

In [7]: df2
Out [8]: 
      Name  Punktzahl
0     Hans         20
1   Jürgen         45
2  Johanna          3
3  Marlene         45

In [9]: df1[~df1["Name"].isin(df2["Name"]) & (df1["Abweichung"] < 0)]
Out [9]: 
    Name  Abweichung  altePunktzahl
6  Tommy          -4             68
Ich wollte aber, dass nur die geschlöscht werden, deren Abweichung < 0 ist. Jürgen z.B. hat eine Abweichung von 0, also ist sie nicht kleiner 0, folglich müsste er in der Liste stehen, er wurde aber doch entfernt. Gleiches gilt für Marlene. Zudem fehler Florian & Iris, die gar nicht in df2 vorkommen und folglich nicht entfernt werden dürfen. Wie bekomme ich das hin, dass alle (und nur diese) Namen aus df1 entfernt werden, deren Name auch in df2 vorkommt und deren Abweichung (in df1) negativ ist?
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

Dann mußt Du Deine Bedingung entsprechend formulieren. Dann ist das ~ falsch geklammert.
Antworten