Python 如何将任何值替换为与系列中的前一个值不在一定范围内的NAN?

Python 如何将任何值替换为与系列中的前一个值不在一定范围内的NAN?,python,pandas,Python,Pandas,我有一个熊猫系列,我想知道一个值是否在前一个值的某个范围内(比如高于或低于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

我有一个熊猫系列,我想知道一个值是否在前一个值的某个范围内(比如高于或低于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

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

df["previous_value"] = df["required_column"].shift(-1)
然后,可以使用

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

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

您可以使用注释中提到的@ALollz的
pct_change
。使用
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
因为您需要state(前面的行值很重要),所以不能只使用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)
def删除异常值(s,i=0):
tmp=s.dropna()
tmp=tmp[i:]
对于枚举中的i,v(tmp.iteritems()):
如果i-1>0:
#替换为自定义条件,tmp.iloc[i-1]是以前的值
如果不是(0.9