我正在尝试对包含 NaN 的 pandas 系列进行缩尾处理。使用掩码可以转义 NaN,但它仅在查找百分位值时转义 NaN,然后也用该值替换 NaN,这不是我想要的。
例如,df 由 1, 2, ..., 98, 99, Inf, NaN 组成。对于 (0.01, 0.01) 缩尾化,结果应为 2, 2, 3, 4, ..., 98, 99, 99, NaN。
使用winsorize直接得到2, 2, 3, 4, ..., 98, 99, 99。我尝试先屏蔽NaN,然后winsorize,最后用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 未正确缩尾,我不明白为什么会发生这种情况。
我不首先删除 NaN 然后进行 winsorize 的原因是需要保留索引。这是大型数据集的一部分,并且该观察的其他变量并不缺失。
有办法(最好是优雅的)来实现我的目标吗?
最佳答案
您需要先屏蔽它。
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 进行缩尾处理,是因为忽略 NaN 会将样本减少到 98,第一个百分位数将是“第 0.98 个”观测值,这本质上是“第 0 个”观测值,因此 1 不被视为已进行缩尾处理。
关于python - 在Python中进行winsorize但忽略nan的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47105278/