如何采取地板和封顶去除异常值

时间:2017-02-13 15:40:22

标签: python pandas

如何计算99%和1%百分位数作为每列的上限和下限,if值> = 99%百分位数然后将该值重新定义为99%百分位数的值;同样,如果值< = 1%百分位数,则将值重新定义为1%百分位值

np.random.seed(2)
df = pd.DataFrame({'value1': np.random.randn(100), 'value2': np.random.randn(100)})
df['lrnval'] = np.where(np.random.random(df.shape[0])>=0.7, 'learning', 'validation')

如果我们有数百列,我们可以使用apply函数而不是do循环吗?

2 个答案:

答案 0 :(得分:1)

您可以先定义一个辅助函数,该函数接受seriesvalue作为参数,并根据上述条件更改该值:

def scale_val(s, val):
    percentiles = s.quantile([0.01,0.99]).values
    if val <= percentiles[0]:
        return percentiles[0]
    elif val >= percentiles[1]:
        return percentiles[1]
    else:
        return val

然后您可以使用pd.DataFrame.applypd.Series.apply

df.apply(lambda s: s.apply(lambda v: scale_val(s,v)))

请注意,如果您处理大量数据,这可能会有点慢,但我建议您先试一试,看看它是否能在合理的时间内解决您的问题。

编辑:

如果您只想获得列df等于&#34;学习&#34;的lrnval行的百分位数,您可以修改该函数以仅计算百分位数该条件为真的行:

def scale_val2(s, val):
    percentiles = s[df.lrnval.eq('learning')].quantile([0.01,0.99]).values
    if val <= percentiles[0]:
        return percentiles[0]
    elif val >= percentiles[1]:
        return percentiles[1]
    else:
        return val

由于有一个包含字符串的列,我假设您不会对其进行任何计算。所以,我会按如下方式更改代码:

df.filter(regex='[^lrnval]').apply(lambda s: s.apply(lambda v: scale_val2(s,v)))

我希望这证明有用。

答案 1 :(得分:1)

根据Abdou的回答,以下内容可能会为您节省一些时间:

for col in df.columns:
    percentiles = df[col].quantile([0.01,0.99]).values
    df[col][df[col] <= percentiles[0]] = percentiles[0]
    df[col][df[col] >= percentiles[1]] = percentiles[1]