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

如何按时间分组用滚动均值填充Pandas DataFrame缺失值?

按时间分组用滚动均值填充Pandas缺失值

问题描述

现有带datetime字段的Pandas DataFrame,需按time(提取自datetime的时分部分)分组,用缺失值前后行的滚动均值填充NaN。尝试的代码无法正常运行:

import pandas as pd
import numpy as np

df = pd.DataFrame({'datetime':['2023-04-20 13:00', '2023-04-21 13:00','2023-04-22 13:00', '2023-04-23 13:00','2023-04-21 14:00', '2023-04-22 14:00', '2023-04-23 14:00'], 'var':[1, 2, np.nan, 3, np.nan, 4, 5]})

df = df.assign(datetime=pd.to_datetime(df.datetime))
df = df.assign(time=df['datetime'].dt.time)

# 无法正常运行的代码
df.assign(var=df.groupby('time', sort=False).var.apply(lambda col: col.fillna(col.rolling(window=2, center=2).mean())))

当前数据

datetime    var
0   2023-04-20 13:00    1.0
1   2023-04-21 13:00    2.0
2   2023-04-22 13:00    NaN
3   2023-04-23 13:00    3.0
4   2023-04-21 14:00    NaN
5   2023-04-22 14:00    4.0
6   2023-04-23 14:00    5.0

期望结果

datetime    var
0   2023-04-20 13:00    1.0
1   2023-04-21 13:00    2.0
2   2023-04-22 13:00    2.5
3   2023-04-23 13:00    3.0
4   2023-04-21 14:00    4.0
5   2023-04-22 14:00    4.0
6   2023-04-23 14:00    5.0

同时询问:是否可以调整计算均值的窗口大小?


解决方案

原代码问题点

  1. rolling的center参数应为布尔值(True/False),而非数值2,这会导致参数错误。
  2. 仅用rolling(window=2).mean()无法覆盖边界缺失值(如14:00组的首个NaN,无前置数据),需结合前后向填充或扩展窗口逻辑。

修正后的代码

import pandas as pd
import numpy as np

df = pd.DataFrame({'datetime':['2023-04-20 13:00', '2023-04-21 13:00','2023-04-22 13:00', '2023-04-23 13:00','2023-04-21 14:00', '2023-04-22 14:00', '2023-04-23 14:00'], 'var':[1, 2, np.nan, 3, np.nan, 4, 5]})

df['datetime'] = pd.to_datetime(df['datetime'])
df['time'] = df['datetime'].dt.time

# 分组后用滚动均值填充,结合前后向填充处理边界
def fill_missing_with_rolling_mean(col):
    # 先计算中心滚动均值(window=3,取当前行+前后各一行),填充中间缺失
    rolling_mean = col.rolling(window=3, center=True, min_periods=1).mean()
    # 再用前后向填充处理剩余边界缺失
    return col.fillna(rolling_mean).fillna(method='bfill').fillna(method='ffill')

df['var'] = df.groupby('time', sort=False)['var'].apply(fill_missing_with_rolling_mean)

print(df)

代码说明

  • rolling(window=3, center=True, min_periods=1):窗口大小为3(当前行+前后各一行),center=True表示以当前行为中心计算均值,min_periods=1保证即使窗口内只有1个有效值也能计算均值,适配边界情况。
  • 先通过滚动均值填充中间缺失,再用bfill(后向填充)和ffill(前向填充)处理剩余的边界NaN,匹配期望结果。

关于窗口大小调整

完全可以调整窗口大小:

  • 若想扩大计算均值的范围,比如取前后2行+当前行,可将window设为5,同时保持center=True。
  • 若只想取前一行和当前行的均值,将window=2且center=False(默认),但需注意这种情况无法覆盖中间缺失的前后值计算(如13:00组的NaN)。
  • 调整后需配合min_periods参数,避免因窗口内有效值不足导致生成新的NaN。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:47:05