python - 在Python中进行winsorize但忽略nan的正确方法

标签 python

我正在尝试对包含 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/

相关文章:

python - 使用 pandas 将附加标题转换为列

python - GroupRectangles Opencv 不工作

python - 相同数据和簇数的不同轮廓分数

python - 我可以用 Cython 创建静态 C 数组吗?

python - Python 中元组列表作为字典的键

python - 在初始查询 sqlalchemy 中限制子集合

python - 删除 pandas 中的前导 NaN

python - Bokeh 中的独立节点和边缘悬停工具?

python - 计算重复平均 python

python - 如果字符串包含逗号(,)空格和其他字符(如(