Mam stosunkowo duży obiekt DataFrame (około miliona wierszy, setki kolumn) i chciałbym przypisać wartości odstające w każdej kolumnie według grupy. Przez "obcinanie klipów dla każdej kolumny według grupy" rozumiem - oblicz kwantyle 5% i 95% dla każdej kolumny w grupie i wartości klipów poza tym zakresem kwantyli.Szybszy sposób usuwania wartości odstających przez grupę w dużych pandach DataFrame
Oto konfiguracja obecnie używam:
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)
a potem, ze moja DataFrame nazywa features
i indeksowane przez DATE
mogę zrobić
grouped = features.groupby(level='DATE')
result = grouped.apply(winsorize_df)
To działa, oprócz tego, że jest to bardzo wolno, prawdopodobnie z powodu zagnieżdżonych wywołań apply
: po jednej w każdej grupie, a następnie po jednej dla każdej kolumny w każdej grupie. Próbowałem pozbyć się drugiego apply
, obliczając kwantyle dla wszystkich kolumn naraz, ale utknąłem próbując ustawić próg każdej kolumny przez inną wartość. Czy istnieje szybszy sposób na wykonanie tej procedury?
Dzięki, to jest dobry wskaźnik, nie zdawałem sobie sprawy, że scipy ma funkcję 'winsorize'. Zakładam jednak, że większe przyspieszenie byłoby możliwe, gdyby istniał sposób na masową operację operacji na DataFrame bez konieczności obsługi kolumn po kolumnie, podobnie jak w przypadku masowej standaryzacji lub normalizacji, np. Http: // stackoverflow.com/questions/12525722/normalize-data-in-pandas –
Czy w każdej grupie jest taka sama liczba dat? – unutbu
grupa według operacji jest według daty, więc każda grupa ma tylko jedną datę. Czy chcesz zapytać, czy każda grupa ma taką samą liczbę rzędów? Odpowiedź brzmi: nie, każda data może (i zazwyczaj ma) mieć inną liczbę wierszy. –