繁体   English   中英

如何用不在熊猫系列中先前值某个范围内的NAN替换任何值?

[英]How can I replace any value with an NAN that is not within a certain range of the previous value in a pandas series?

我有一个熊猫系列,我想找出一个值是否在先前值的某个范围内(例如高于或低于10%),如果不是,则将其替换为NAN。 我不确定如何进行。 标准离群值消除技术主要处理整体标准差等。

如何在每个步骤中访问先前的值并对其进行操作?

2018-09-06        NaN
2018-09-07        NaN
2018-09-08        NaN
2018-09-09    662.105
2018-09-10    651.010
2018-09-11    454.870
2018-09-12    597.840
2018-09-13    662.405
2018-09-14    660.735
2018-09-15    671.065
2018-09-16    668.485
2018-09-17    666.205
2018-09-18    663.620
2018-09-19    663.320
2018-09-20    662.715
2018-09-21    665.145
2018-09-22    663.015
2018-09-23    663.775
2018-09-24    662.860
2018-09-25    663.315
2018-09-26    665.600
2018-09-27    664.080
2018-09-28    661.800
2018-09-29    659.825
2018-09-30    659.370
2018-10-01        NaN
2018-10-02        NaN
2018-10-03        NaN
2018-10-04        NaN

您可以将pct_change用作注释中提到的@ALollz。 使用Series.loc将不满足条件的值设置为False。

ts.loc[ts.pct_change().abs() > 0.1] = np.nan

2018-09-06        NaN
2018-09-07        NaN
2018-09-08        NaN
2018-09-09    662.105
2018-09-10    651.010
2018-09-11        NaN
2018-09-12        NaN
2018-09-13        NaN
2018-09-14    660.735
2018-09-15    671.065
2018-09-16    668.485
2018-09-17    666.205
2018-09-18    663.620
2018-09-19    663.320
2018-09-20    662.715
2018-09-21    665.145
2018-09-22    663.015
2018-09-23    663.775
2018-09-24    662.860
2018-09-25    663.315
2018-09-26    665.600
2018-09-27    664.080
2018-09-28    661.800
2018-09-29    659.825
2018-09-30    659.370
2018-10-01        NaN
2018-10-02        NaN
2018-10-03        NaN
2018-10-04        NaN

您可以使用shift方法创建一个新列以获取以前的值。

df["previous_value"] = df["required_column"].shift(-1)

然后可以使用

df["percent_change"] = (df["previous_value"]-df["required_column"])/df["previous_value"]

您现在可以根据您对百分比变化的要求进行过滤

因为您需要状态(前一行的值很重要),所以您不能只使用apply或numpy操作,而是需要遍历各行。 这是可以执行的操作,每次找到异常值时,它将其设置为Nan,然后递归重新启动自身,以使异常值不会影响以下值。 为此,系列索引必须唯一。

def remove_outliers(s, i=0):
    tmp = s.dropna()
    tmp = tmp[i:]
    for i, v in enumerate(tmp.iteritems()):
        if i-1 > 0:
            #replace with custom condition, tmp.iloc[i-1] is the previous value
            if not (0.9< v[1]/tmp.iloc[i-1] <1.1):
                s.loc[v[0]] = None
                remove_outliers(s,i)
                break

s =pd.Series([55,51,52,53,54,None,None,600,49,48,50,51,7,None,None,52,None])
remove_outliers(s)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM