Wie implementiere ich 'in' und 'not in' für einen Pandas DataFrame?
Pandas bietet zwei Methoden an: Series.isin
und DataFrame.isin
für Serien- bzw. DataFrames.
Filtern von DataFrame basierend auf EINER Spalte (gilt auch für Serien)
Das häufigste Szenario ist das Anwenden einer isin
Bedingung auf eine bestimmte Spalte, um Zeilen in einem DataFrame zu filtern.
df = pd.DataFrame({'countries': ['US', 'UK', 'Germany', np.nan, 'China']})
df
countries
0 US
1 UK
2 Germany
3 China
c1 = ['UK', 'China'] # list
c2 = {'Germany'} # set
c3 = pd.Series(['China', 'US']) # Series
c4 = np.array(['US', 'UK']) # array
Series.isin
akzeptiert verschiedene Typen als Eingaben. Im Folgenden finden Sie alle gültigen Methoden, um das zu erhalten, was Sie möchten:
df['countries'].isin(c1)
0 False
1 True
2 False
3 False
4 True
Name: countries, dtype: bool
# `in` operation
df[df['countries'].isin(c1)]
countries
1 UK
4 China
# `not in` operation
df[~df['countries'].isin(c1)]
countries
0 US
2 Germany
3 NaN
# Filter with `set` (tuples work too)
df[df['countries'].isin(c2)]
countries
2 Germany
# Filter with another Series
df[df['countries'].isin(c3)]
countries
0 US
4 China
# Filter with array
df[df['countries'].isin(c4)]
countries
0 US
1 UK
Filtern Sie nach vielen Spalten
Manchmal möchten Sie eine In-Mitgliedschaftsprüfung mit einigen Suchbegriffen auf mehrere Spalten anwenden.
df2 = pd.DataFrame({
'A': ['x', 'y', 'z', 'q'], 'B': ['w', 'a', np.nan, 'x'], 'C': np.arange(4)})
df2
A B C
0 x w 0
1 y a 1
2 z NaN 2
3 q x 3
c1 = ['x', 'w', 'p']
isin
Verwenden Sie Folgendes, um die Bedingung auf beide Spalten "A" und "B" anzuwenden DataFrame.isin
:
df2[['A', 'B']].isin(c1)
A B
0 True True
1 False False
2 False False
3 False True
Um Zeilen beizubehaltenTrue
, in denen sich mindestens eine Spalte befindet , können wir any
entlang der ersten Achse Folgendes verwenden:
df2[['A', 'B']].isin(c1).any(axis=1)
0 True
1 False
2 False
3 True
dtype: bool
df2[df2[['A', 'B']].isin(c1).any(axis=1)]
A B C
0 x w 0
3 q x 3
Beachten Sie, dass Sie, wenn Sie jede Spalte durchsuchen möchten, den Schritt zur Spaltenauswahl einfach weglassen und ausführen müssen
df2.isin(c1).any(axis=1)
In ähnlicher Weise zu Reihen zu behalten , wo alle Spalten sindTrue
, die Verwendung all
in der gleichen Weise wie zuvor.
df2[df2[['A', 'B']].isin(c1).all(axis=1)]
A B C
0 x w 0
Bemerkenswerte Mentions: numpy.isin
, query
, Listenkomprehensionen (string data)
Zusätzlich zu den oben beschriebenen Methoden können Sie auch das numpy-Äquivalent verwenden : numpy.isin
.
# `in` operation
df[np.isin(df['countries'], c1)]
countries
1 UK
4 China
# `not in` operation
df[np.isin(df['countries'], c1, invert=True)]
countries
0 US
2 Germany
3 NaN
Warum ist es eine Überlegung wert? NumPy-Funktionen sind aufgrund des geringeren Overheads normalerweise etwas schneller als ihre Pandas-Entsprechungen. Da dies eine elementweise Operation ist, die nicht von der Indexausrichtung abhängt, gibt es nur sehr wenige Situationen, in denen diese Methode kein geeigneter Ersatz für Pandas ist isin
.
Pandas-Routinen sind normalerweise iterativ, wenn mit Zeichenfolgen gearbeitet wird, da Zeichenfolgenoperationen schwer zu vektorisieren sind. Es gibt viele Hinweise darauf, dass das Listenverständnis hier schneller sein wird. . Wir greifen in
jetzt auf einen Scheck zurück.
c1_set = set(c1) # Using `in` with `sets` is a constant time operation...
# This doesn't matter for pandas because the implementation differs.
# `in` operation
df[[x in c1_set for x in df['countries']]]
countries
1 UK
4 China
# `not in` operation
df[[x not in c1_set for x in df['countries']]]
countries
0 US
2 Germany
3 NaN
Die Angabe ist jedoch viel unhandlicher. Verwenden Sie sie daher nur, wenn Sie wissen, was Sie tun.
Schließlich gibt es DataFrame.query
noch etwas, das in dieser Antwort behandelt wurde . numexpr FTW!