Ich habe ein relativ großes DataFrame-Objekt (etwa eine Million Zeilen, Hunderte von Spalten), und ich möchte Ausreißer in jeder Spalte nach Gruppe ausschneiden. Mit "Clip-Ausreißer für jede Spalte nach Gruppe" meine ich - berechne die 5% - und 95% -Quantile für jede Spalte in einer Gruppe und trenne Werte außerhalb dieses Quantilbereichs.Schneller Weg zum Entfernen von Ausreißern nach Gruppe in großen Pandas DataFrame
Hier ist das Setup ich zur Zeit mit:
def winsorize_series(s):
q = s.quantile([0.05, 0.95])
if isinstance(q, pd.Series) and len(q) == 2:
s[s < q.iloc[0]] = q.iloc[0]
s[s > q.iloc[1]] = q.iloc[1]
return s
def winsorize_df(df):
return df.apply(winsorize_series, axis=0)
und dann mit meinem Dataframe features
und indiziert durch DATE
genannt, kann ich
grouped = features.groupby(level='DATE')
result = grouped.apply(winsorize_df)
Dies funktioniert nicht, es sei denn, dass es sehr langsam, vermutlich aufgrund der verschachtelten Aufrufe apply
: eine für jede Gruppe und dann eine für jede Spalte in jeder Gruppe. Ich versuchte, die zweite apply
loszuwerden, indem ich Quantile für alle Spalten gleichzeitig berechnete, aber steckte versuchend, jede Spalte durch einen anderen Wert zu schwellen. Gibt es einen schnelleren Weg, um dieses Verfahren durchzuführen?
Danke, das ist ein guter Zeiger, ich wusste nicht, dass Scipy eine "Winsorize" -Funktion hatte. Ich gehe jedoch davon aus, dass eine substantielle Beschleunigung erreicht werden würde, wenn es eine Möglichkeit gäbe, die Operation im Bulk auf dem DataFrame auszuführen, ohne Spalte für Spalte arbeiten zu müssen, ähnlich wie man standardisieren oder normalisieren könnte, zB http: // stackoverflow.com/questions/12525722/normalize-data-in-pandas –
Gibt es in jeder Gruppe die gleiche Anzahl von Daten? – unutbu
Die Gruppe nach Vorgang ist nach Datum, daher hat jede Gruppe nur ein Datum. Willst du fragen, ob jede Gruppe die gleiche Anzahl von Zeilen hat? Die Antwort darauf ist nein, jedes Datum kann (und hat typischerweise) eine andere Anzahl von Zeilen. –