如何移除Pandas DataFrame时间序列中的数据骤降异常值
处理Pandas时间序列中的递减异常值
看起来你需要修复一个本该保持递增趋势的时间序列数据,处理那些突然出现的低值异常。下面我会用两种简洁的方法实现你要的两种结果,先从构造示例数据开始:
import pandas as pd # 构造你提供的示例数据 data = { 'date': ['22-01-17', '22-01-18', '22-01-19', '22-01-20', '22-01-21', '22-01-22', '22-01-23', '22-01-24'], 'value': [0, 45, 78, 98, 6, 7, 4, 101] } df = pd.DataFrame(data) df['date'] = pd.to_datetime(df['date'], format='%y-%m-%d') df = df.set_index('date')
结果一:用前一个有效值填充异常值
因为你的数据理论上是递增的,所以到当前位置的累积最大值就是我们需要保留的"前一个有效值"。Pandas的cummax()方法可以直接帮我们实现这个需求,它会沿着序列保留每个位置之前的最大值,自动替换掉那些低于最大值的异常值:
# 复制原数据避免修改原始数据 df_filled = df.copy() # 用累积最大值填充异常值 df_filled['value'] = df_filled['value'].cummax() # 输出结果 print(df_filled)
运行后你会得到:
value date 2022-01-17 0 2022-01-18 45 2022-01-19 78 2022-01-20 98 2022-01-21 98 2022-01-22 98 2022-01-23 98 2022-01-24 101
完全符合你要的第一种结果,而且这个方法不需要循环,处理大型数据集也很高效。
结果二:将异常值替换为NaN
这里我们需要先标记出那些低于"到当前位置的累积最大值"的异常值,然后把它们替换为NaN:
# 复制原数据 df_nan = df.copy() # 计算到每个位置的累积最大值 cumulative_max = df_nan['value'].cummax() # 创建掩码:标记当前值小于累积最大值的位置(这些就是异常值) outlier_mask = df_nan['value'] < cumulative_max # 将异常值替换为NaN df_nan.loc[outlier_mask, 'value'] = pd.NA # 输出结果 print(df_nan)
运行后得到:
value date 2022-01-17 0 2022-01-18 45 2022-01-19 78 2022-01-20 98 2022-01-21 <NA> 2022-01-22 <NA> 2022-01-23 <NA> 2022-01-24 101
刚好是你要的第二种结果。
补充说明
如果你的数据要求是严格递增(即每个值必须大于前一个,不能相等),只需要稍微调整掩码的条件:
# 严格递增的情况:当前值小于前一个有效值(即前一个位置的累积最大值) outlier_mask = df_nan['value'] < cumulative_max.shift(1) # 注意第一个位置没有前值,所以要排除 outlier_mask.iloc[0] = False
这样就能过滤掉那些等于前值的情况,不过根据你的示例数据,用cummax的默认逻辑已经完全满足需求了。
内容的提问来源于stack exchange,提问作者Glenn Pierce
相关产品推荐
相关产品推荐

