You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中实现基于星期几的中心滚动窗口异常值检测?

实现基于星期几的同周几滚动窗口异常值检测

核心思路是按星期几分组,同一星期几的日期按时间顺序排列后,用窗口大小为5的中心滚动窗口,就能自动取到当前日期的往前2个、往后2个同星期几的数据(共5个)。具体实现步骤如下:

步骤1:添加星期几标识列

给原DataFrame添加一列标记日期对应的星期几,用pd.Series.dt.weekday,其中0代表周一,1代表周二,以此类推。

步骤2:按星期几分组计算滚动统计量

对每个星期几的分组,单独做滚动窗口计算(窗口大小5,中心=True),这样每个日期对应的窗口就是同星期几的前后各2个数据。

步骤3:合并统计量并替换异常值

把分组计算得到的均值、标准差合并回原DataFrame,然后按照原逻辑检测异常值并替换。

完整代码

import pandas as pd
import numpy as np

np.random.seed(0)

# 生成原始数据
dates = pd.date_range(start='2022-01-01', end='2023-12-31', freq='D')
prices1 = np.random.randint(10, 100, size=len(dates))
prices2 = np.random.randint(20, 120, size=len(dates)).astype(float)
df = pd.DataFrame({'Date': dates, 'Price1': prices1, 'Price2': prices2})

# 添加星期几列,0=周一,1=周二...6=周日
df['dow'] = df['Date'].dt.weekday

# 按星期几分组,计算滚动均值和标准差
def rolling_stats(group):
    # 确保分组内数据按日期排序(生成数据时已有序,此处做保险)
    group = group.sort_values('Date')
    r = group['Price1'].rolling(window=5, center=True)
    group['roll_mean'] = r.mean()
    group['roll_std'] = r.std()
    return group

# 应用分组计算并重置索引
df = df.groupby('dow').apply(rolling_stats).reset_index(drop=True)

# 计算上下限并替换异常值
price_up = df['roll_mean'] + 2 * df['roll_std']
price_low = df['roll_mean'] - 2 * df['roll_std']

mask_upper = df['Price1'] > price_up
mask_lower = df['Price1'] < price_low

df.loc[mask_upper, 'Price1'] = df['roll_mean']
df.loc[mask_lower, 'Price1'] = df['roll_mean']

# 可查看周一的数据验证窗口逻辑
print(df[df['dow'] == 0].head(10))

关键说明

  • 分组后每个组都是同一星期几的日期,按时间排序后,rolling(window=5, center=True)会自动以当前行为中心,取前后各2行数据,完全匹配你要的“往前2个同星期几+往后2个同星期几”的需求。
  • 分组的首尾2行数据因无法凑齐5个样本(比如第一个周一没有往前2个周一),滚动统计量会是NaN,你可以根据需求处理这些值(比如保留原始数据,或用前/后向填充)。

内容的提问来源于stack exchange,提问作者r ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:12:51