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