Effiziente Möglichkeit, mehrere Filter auf Pandas DataFrame oder Series anzuwenden
Habe ich ein Szenario, wo ein Benutzer möchte, wenden Sie verschiedene Filter auf ein Pandas DataFrame oder Series-Objekt. Im wesentlichen, ich möchte effizient Kette eine Reihe von filtern (Vergleich operations) zusammen, die angegeben werden, die zur Laufzeit durch den Benutzer.
Müssen die Filter Additiv (aka jeden angewendet werden sollte, schmalen Ergebnisse).
Ich bin derzeit mit reindex()
aber dies erzeugt ein neues Objekt jedes mal und Kopien der zugrunde liegenden Daten (sofern verstehe ich die Dokumentation richtig). So, könnte dies wirklich ineffizient, wenn die Filterung einer großen Serie oder DataFrame.
Ich denke, dass mit apply()
, map()
oder etwas ähnliches wäre vielleicht besser. Ich bin ziemlich neu Pandas obwohl so immer noch versuchen, wickeln Sie meinen Kopf herum alles.
TL;DR
Möchte ich ein Wörterbuch das folgende Formular aus und gelten jede operation, die zu einer bestimmten Serie Objekt-und einen "filtered" - Serie Objekt.
relops = {'>=': [1], '<=': [1]}
Lange Beispiel
Ich beginne mit einem Beispiel, was ich derzeit habe und nur die Filterung ein einzelnes Series-Objekt. Unten ist die Funktion, die ich derzeit benutze:
def apply_relops(series, relops):
"""
Pass dictionary of relational operators to perform on given series object
"""
for op, vals in relops.iteritems():
op_func = ops[op]
for val in vals:
filtered = op_func(series, val)
series = series.reindex(series[filtered])
return series
Den Benutzer liefert ein dictionary mit den Operationen, die Sie ausführen möchten:
>>> df = pandas.DataFrame({'col1': [0, 1, 2], 'col2': [10, 11, 12]})
>>> print df
>>> print df
col1 col2
0 0 10
1 1 11
2 2 12
>>> from operator import le, ge
>>> ops ={'>=': ge, '<=': le}
>>> apply_relops(df['col1'], {'>=': [1]})
col1
1 1
2 2
Name: col1
>>> apply_relops(df['col1'], relops = {'>=': [1], '<=': [1]})
col1
1 1
Name: col1
Wieder, das "problem" mit meinem obigen Ansatz ist, dass ich denke, es gibt eine Menge von möglicherweise unnötige kopieren der Daten für die in-zwischen den Schritten.
Außerdem würde ich gerne erweitern, so dass das Wörterbuch übergeben, können die Spalten operator und filtern eine ganze DataFrame auf der Grundlage der input-Wörterbuch. Aber ich gehe davon aus, dass was auch immer arbeitet für die Serie können problemlos erweitert werden, um ein DataFrame.
InformationsquelleAutor der Frage durden2.0 | 2012-11-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Pandas (und numpy) ermöglichen Boolesche Indexierung, die viel effizienter:
Wenn Sie möchten, schreiben Sie Hilfsfunktionen für diese, sollten Sie etwas entlang diesen Linien:
Update: pandas 0.13 verfügt über eine query-Methode für diese Art von use cases, vorausgesetzt, die Spalte Namen sind gültige Bezeichner die folgenden Werke (und kann es effizienter sein, für den großen Rahmen, wie es verwendet numexpr hinter den kulissen):
InformationsquelleAutor der Antwort Andy Hayden
Chaining Bedingungen schafft lange Zeilen, von denen abgeraten wird pep8.
Mit Hilfe der .query-Methode, Kräfte zu verwenden, Zeichenfolgen, die ist mächtig, aber unpythonic und nicht sehr dynamisch.
Nachdem jeder der Filter ist im Ort, ein Ansatz ist
np.logisch funktioniert und ist schnell, aber nicht mehr als zwei Argumente, die behandelt werden functools.reduzieren.
Beachten Sie, dass dies noch einige Entlassungen: a) abkürzens geschieht nicht auf globaler Ebene b) an Jede der einzelnen Bedingungen ausgeführt wird, die auf das ganze anfängliche Daten. Noch habe ich erwarten, dass diese leistungsfähig genug für viele Anwendungen und es ist sehr gut lesbar.
InformationsquelleAutor der Antwort Gecko
Einfachste Aller Lösungen:
Verwenden:
Ein weiteres Beispiel, Zum filtern der dataframe für Werte gehörenden Feb-2018, verwenden Sie den code unten
InformationsquelleAutor der Antwort Gil Baggio
Seit pandas 0.22 update, Vergleich Optionen sind verfügbar, wie:
und viele mehr. Diese Funktionen return boolean-array. Mal sehen, wie wir Sie nutzen können:
InformationsquelleAutor der Antwort YOLO
Warum nicht?
Demo:
Ergebnis:
Können Sie sehen, dass die Spalte " a " wurde gefiltert, wo ein >=2.
Dies ist etwas schneller (Eingabe von Zeit, nicht die Leistung) als operator-chaining. Man könnte natürlich setzen Sie den import am Anfang der Datei.
InformationsquelleAutor der Antwort Obol