62_Pandas extrahiert bedingt Zeilen von pandas.DataFrame
Verwenden Sie die Methode query(), um Zeilen basierend auf Bedingungen für die Spaltenwerte eines pandas.DataFrame zu extrahieren. Dies ist praktisch, da Sie bedingte Spezifikationen mithilfe von Vergleichsoperatoren und Zeichenfolgenmethoden sowie Kombinationen mehrerer Bedingungen prägnant beschreiben können.
Inhaltsverzeichnis
- Verwenden Sie Vergleichsoperatoren, um Bedingungen anzugeben
- Verwenden Sie den in-Operator für die bedingte Spezifikation (entspricht isin()).
- Geben Sie Bedingungen mit String-Methoden an
- Wenn Werte NaN oder None fehlen
- Indexbedingung
- Geben Sie mehrere Bedingungen an
- Spaltennamen, die Leerzeichen oder Punkte enthalten, mit „`“ einschließen.
- Aktualisieren Sie das Originalobjekt mit dem Inplace-Parameter
Informationen zur Bedingungsspezifikation des Booleschen Index finden Sie im folgenden Artikel.
Die Pandas-Version des Beispielcodes in diesem Artikel ist Version 2.0.3. Beachten Sie, dass das Verhalten je nach Version variieren kann.
import pandas as pd
print(pd.__version__)
# 2.0.3
df = pd.read_csv('data/sample_pandas_normal.csv')
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
Verwenden Sie Vergleichsoperatoren, um Bedingungen anzugeben
In Pandas können Sie Vergleichsoperatoren verwenden, um Zeilen wie folgt zu extrahieren:
print(df[df['age'] < 25])
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
Ähnliche Bedingungen können über Strings mit der Methode query() angegeben werden.
print(df.query('age < 25'))
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
Stellen Sie einem Variablennamen ein @ voran, um diese Variable in einer Bedingungszeichenfolge zu verwenden.
val = 25
print(df.query('age < @val'))
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
Bereiche können mithilfe von zwei Vergleichsoperatoren angegeben werden, genau wie die bedingten Spezifikationen von Python.
print(df.query('30 <= age < 50'))
# name age state point
# 1 Bob 42 CA 92
# 5 Frank 30 NY 57
Sie können auch Spalten vergleichen und vergleichen, indem Sie Berechnungen mit arithmetischen Operatoren durchführen.
print(df.query('age < point / 3'))
# name age state point
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
==, != zeigen Übereinstimmung und Nichtübereinstimmung an. Beachten Sie, dass die Zeichenfolgen in der Bedingungszeichenfolge in Anführungszeichen gesetzt werden müssen.
Doppelte Anführungszeichen können in Zeichenfolgen verwendet werden, die in einfache Anführungszeichen eingeschlossen sind, und einfache Anführungszeichen können in Zeichenfolgen verwendet werden, die in doppelte Anführungszeichen eingeschlossen sind. Die gleiche Notation kann verwendet werden, indem man sie mit einem Backslash \ maskiert.
print(df.query('state == "CA"'))
# name age state point
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
Machen Sie sich bei der Verwendung von Variablen keine Sorgen über Anführungszeichen.
s = 'CA'
print(df.query('state != @s'))
# name age state point
# 0 Alice 24 NY 64
# 3 Dave 68 TX 70
# 5 Frank 30 NY 57
Verwenden Sie den in-Operator für die bedingte Spezifikation (entspricht isin()).
isin() ist eine Methode, die bool (True, False) zurückgibt, um zu bestimmen, ob das Spaltenelement (pandas.Series) in der Parameterliste enthalten ist. Dies kann zum Extrahieren von Zeilen verwendet werden, in denen Elemente in einer Spalte mit einem bestimmten Wert übereinstimmen.
print(df[df['state'].isin(['NY', 'TX'])])
# name age state point
# 0 Alice 24 NY 64
# 3 Dave 68 TX 70
# 5 Frank 30 NY 57
Das Äquivalent kann mit in in der Methode query() erfolgen.
print(df.query('state in ["NY", "TX"]'))
# name age state point
# 0 Alice 24 NY 64
# 3 Dave 68 TX 70
# 5 Frank 30 NY 57
Als besondere Verwendung wird == für Listen auf die gleiche Weise gehandhabt.
print(df.query('state == ["NY", "TX"]'))
# name age state point
# 0 Alice 24 NY 64
# 3 Dave 68 TX 70
# 5 Frank 30 NY 57
Sie können auch Listenvariablen verwenden.
l = ['NY', 'TX']
print(df.query('state in @l'))
# name age state point
# 0 Alice 24 NY 64
# 3 Dave 68 TX 70
# 5 Frank 30 NY 57
Geben Sie Bedingungen mit String-Methoden an
Bedingungen für den vollständigen String-Abgleich können mit == oder oben angegeben werden, Bedingungen für einen teilweisen String-Abgleich können jedoch mit den String-Methoden str.xxx() angegeben werden.
Beziehen Sie sich auf die folgende Methode:
- str.contains(): Enthält eine bestimmte Zeichenfolge
- str.endswith(): endet mit einer bestimmten Zeichenfolge
- str.startswith(): Beginnen Sie mit einer bestimmten Zeichenfolge
- str.match(): Muster für reguläre Ausdrücke abgleichen.
Sie können auch in query() verwendet werden, allerdings nicht kompakter als die boolesche Indizierung.
print(df.query('name.str.endswith("e")'))
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
print(df.query('name.str.contains("li")'))
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
String-Methoden können verwendet werden, indem eine Spalte mit einem anderen dtype-Typ als string mithilfe von astype() in den String-Typ str konvertiert wird. Dies kann auch mit query() angegeben werden.
print(df.query('age.astype("str").str.endswith("8")'))
# name age state point
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
Wenn Werte NaN oder None fehlen
Beachten Sie, dass Sie eine Fehlermeldung erhalten, wenn Sie String-Methoden als Bedingungen für Spalten mit fehlenden Werten NaN oder None verwenden.
df.at[0, 'name'] = None
print(df)
# name age state point
# 0 None 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
# print(df.query('name.str.endswith("e")'))
# ValueError: unknown type object
Bei vielen String-Methoden kann der Parameter na einen Wert angeben, um das Ergebnis „None“ oder den fehlenden Wert „NaN“ zu ersetzen. Geben Sie True an, um Zeilen mit fehlenden Werten zu extrahieren, oder False, um Zeilen mit fehlenden Werten nicht zu extrahieren.
print(df[df['name'].str.endswith('e', na=False)])
# name age state point
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
Argumente können auf die gleiche Weise wie query() angegeben werden.
print(df.query('name.str.endswith("e", na=False)'))
# name age state point
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
Indexbedingung
Kriterien (Zeilennamen) können mit index.index angegeben werden.
df = pd.read_csv('data/sample_pandas_normal.csv')
print(df.query('index % 2 == 0'))
# name age state point
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
Wenn der Index einen Namen hat, kann es sich um diesen Namen oder um den Index handeln.
df_name = df.set_index('name')
print(df_name)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Charlie 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
print(df_name.query('name.str.endswith("e")'))
# age state point
# name
# Alice 24 NY 64
# Charlie 18 CA 70
# Dave 68 TX 70
print(df_name.query('index.str.endswith("e")'))
# age state point
# name
# Alice 24 NY 64
# Charlie 18 CA 70
# Dave 68 TX 70
Geben Sie mehrere Bedingungen an
Bei der Angabe mehrerer Bedingungen mit einem booleschen Index lautet die Beschreibung wie folgt.
print(df[(df['age'] < 25) & (df['point'] > 65)])
# name age state point
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
Die Methode query() kann wie folgt geschrieben werden. Klammern sind nicht für jede Bedingung erforderlich, AND (und) kann & oder und sein.
print(df.query('age < 25 & point > 65'))
# name age state point
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
print(df.query('age < 25 and point > 65'))
# name age state point
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
ODER (oder), | oder oder sind alle akzeptabel.
print(df.query('age < 20 | point > 80'))
# name age state point
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
print(df.query('age < 20 or point > 80'))
# name age state point
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
NICHT (negativ) nicht.
print(df.query('not age < 25 and not point > 65'))
# name age state point
# 5 Frank 30 NY 57
Das Gleiche gilt für drei oder mehr Bedingungen, aber die Ergebnisse variieren je nach Reihenfolge, z. B. & hat Vorrang vor |, daher ist es sicherer, den Teil, der zuerst verarbeitet wird, explizit in Klammern zu setzen.
print(df.query('age == 24 | point > 80 & state == "CA"'))
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 4 Ellen 24 CA 88
print(df.query('(age == 24 | point > 80) & state == "CA"'))
# name age state point
# 1 Bob 42 CA 92
# 4 Ellen 24 CA 88
Spaltennamen, die Leerzeichen oder Punkte enthalten, mit „`“ einschließen.
Seien Sie vorsichtig mit den Spaltennamen, wenn Sie die Methode query() verwenden. Ändern Sie beispielsweise die Spaltennamen wie folgt.
df.columns = ['0name', 'age.year', 'state name', 3]
print(df)
# 0name age.year state name 3
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
Die Verwendung eines Spaltennamens, der nicht als Python-Variablenname gültig ist, führt zu einem Fehler. Beispielsweise sind Spaltennamen, die mit einer Zahl beginnen, Spaltennamen, die „.“ oder Leerzeichen enthalten, allesamt falsch.
# print(df.query('0name.str.endswith("e")'))
# SyntaxError: invalid syntax
# print(df.query('age.year < 25'))
# UndefinedVariableError: name 'age' is not defined
# print(df.query('state name == "CA"'))
# SyntaxError: invalid syntax
Muss in „`“ eingeschlossen werden.
print(df.query('`0name`.str.endswith("e")'))
# 0name age.year state name 3
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
print(df.query('`age.year` < 25'))
# 0name age.year state name 3
# 0 Alice 24 NY 64
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
print(df.query('`state name` == "CA"'))
# 0name age.year state name 3
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88
Der Fehler tritt auch dann auf, wenn numerische Spaltennamen in „`“ eingeschlossen sind. Wenn Sie die Bedingung mithilfe einer booleschen Indizierung angeben, gibt es kein Problem.
# print(df.query('3 > 75'))
# KeyError: False
# print(df.query('`3` > 75'))
# UndefinedVariableError: name 'BACKTICK_QUOTED_STRING_3' is not defined
print(df[df[3] > 75])
# 0name age.year state name 3
# 1 Bob 42 CA 92
# 4 Ellen 24 CA 88
Aktualisieren Sie das Originalobjekt mit dem Inplace-Parameter
In den bisherigen Beispielen wird ein neuer pandas.DataFrame zurückgegeben, der die über query() extrahierten Zeilen enthält, und die ursprünglichen Objekte bleiben unberührt. Der Parameter inplace=True ändert das ursprüngliche Objekt selbst.
df = pd.read_csv('data/sample_pandas_normal.csv')
df.query('age > 25', inplace=True)
print(df)
# name age state point
# 1 Bob 42 CA 92
# 3 Dave 68 TX 70
# 5 Frank 30 NY 57