Ich habe ein relativ großes DataFrame-Objekt (ungefähr 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.
Hier ist das Setup, das ich gerade verwende:
%Vor% und dann, mit meinem DataFrame namens features
und indiziert von DATE
, kann ich
Dies funktioniert, außer dass es sehr langsam ist, vermutlich aufgrund der verschachtelten Aufrufe von apply
: eins für jede Gruppe und dann eins für jede Spalte in jeder Gruppe. Ich versuchte, die zweite apply
loszuwerden, indem ich Quantile für alle Spalten gleichzeitig berechnete, aber ich blieb stecken und versuchte, jede Spalte mit einem anderen Wert zu schwellen. Gibt es einen schnelleren Weg, um dieses Verfahren durchzuführen?
In scipy.stats gibt es eine Winsorize-Funktion .mstats , die Sie möglicherweise verwenden möchten. Beachten Sie jedoch, dass es geringfügig andere Werte als winsorize_series
zurückgibt:
Die Verwendung von mstats.winsorize
anstelle von winsorize_series
ist vielleicht (abhängig von N, M, P) ~ 1.5x schneller:
Ich habe einen ziemlich einfachen Weg gefunden, dies zu erreichen, indem ich die Transformationsmethode in Pandas benutze.
%Vor% Eine gute Möglichkeit, dies zu erreichen, ist die Vektorisierung. Und dafür liebe ich np.where
.
Zum Vergleich habe ich die Funktion von scipy
in eine Funktion eingepackt:
Aber wie Sie sehen können, obwohl meine Funktion ziemlich schnell ist, ist sie immer noch weit von der Scipy-Implementierung entfernt:
%Vor%Wenn Sie mehr über die Beschleunigung von Pandas-Code lesen möchten, würde ich vorschlagen, Optimierung Pandas für die Geschwindigkeit und Von Python zu Numpy .