2017-11-03 138 views
0

我想winsorize包含NaN的熊貓系列。使用掩碼可以逃脫NaN,但它只能在找到百分數值時逃脫NaN,然後​​用該值替換NaN,這不是我想要的。例如,df由1,2,...,98,99,Inf,NaN組成。對於(0.01,0.01)揮杆,結果應該是2,2,3,4,...,98,99,99,NaN。適當的方式來winsorize,但忽略nan在Python

直接使用winsorize會產生2,3,4,...,98,99,99。我嘗試先屏蔽NaN,然後​​winsorize,最後用NaN代替原來的NaN:NaN:

import numpy as np 
import pandas as pd 
from scipy.stats.mstats import winsorize 
df = pd.DataFrame(list(range(1,99))+[np.Inf, np.NaN]) 
np.where(df.isnull(), np.nan, winsorize(np.ma.masked_invalid(df),limits=(0.01,0.01))) 

然而,結果現在是1,2,3,...,98,99,99,NaN。最小的數字1沒有正確winsorized,我不明白爲什麼會發生這種情況。

我不首先放棄NaNs然後winsorize的原因是該索引需要保留。這是一個大型數據集的一部分,並且該觀察的其他變量不會丟失。

有沒有一種方法(最好是優雅)來實現我的目標?

回答

0

您需要先將其遮罩。

df = pd.DataFrame({'A':list(range(1,99))+[np.Inf, np.NaN]}) 
df.loc[mask, 'A'] = winsorize(df['A'].loc[mask],limits=0.10) 

爲什麼1不winsorised是因爲忽略的NaN將樣品降低至98,第一百分位數將是「0.98th」觀察,這在本質上是「第0」的觀察,因而1不考慮其原因被winsorised。