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

如何在Pandas中按列分组生成滚动均值并递推填充NaN

按分组实现带NaN递推填充的滚动均值计算

原生的groupby().rolling(2).mean()无法满足需求——它只会用原始数据中的非NaN值计算均值,遇到NaN时不会用之前算出的滚动均值递推填充并继续计算。这种场景下,循环逐行处理每个分组是可行的解决方案。

示例实现

首先构造示例输入DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'col2': ['A', 'A', 'A', 'A', 'B', 'B', 'B'],
    'col3': [10, 20, np.nan, np.nan, 30, np.nan, 50]
})

然后用循环实现递推逻辑:

# 初始化滚动均值列
df['rolling_mean'] = np.nan

# 按col2分组遍历处理
for group_name, group_data in df.groupby('col2'):
    group_indices = group_data.index
    group_size = len(group_data)
    
    # 分组行数不足2,无法计算窗口2的均值,直接跳过
    if group_size < 2:
        continue
    
    # 初始化分组第一个行的有效值
    prev_value = group_data['col3'].iloc[0]
    
    # 处理分组第二个行
    curr_value = group_data['col3'].iloc[1]
    # 若当前值为NaN,用分组第一个行的原始值填充(此时无历史均值)
    if pd.isna(curr_value):
        curr_value = prev_value
    # 计算第一个滚动均值
    first_mean = (prev_value + curr_value) / 2
    df.loc[group_indices[1], 'rolling_mean'] = first_mean
    
    # 维护递推所需的变量
    prev_mean = first_mean
    prev_value = curr_value
    
    # 处理分组从第三个行开始的所有行
    for i in range(2, group_size):
        curr_value = group_data['col3'].iloc[i]
        # 若当前值为NaN,用上一次的滚动均值填充
        if pd.isna(curr_value):
            curr_value = prev_mean
        # 计算当前滚动均值
        current_mean = (prev_value + curr_value) / 2
        df.loc[group_indices[i], 'rolling_mean'] = current_mean
        
        # 更新变量,用于下一行递推
        prev_value = curr_value
        prev_mean = current_mean

运行结果

col2col3rolling_mean
A10.0NaN
A20.015.0
ANaN17.5
ANaN16.25
B30.0NaN
BNaN30.0
B50.040.0

核心逻辑

  • 对每个分组逐行处理,确保NaN值被**上一次计算出的滚动均值(或初始原始值)**填充后,再计算新的滚动均值
  • 通过prev_value和prev_mean两个变量,分别记录上一行的有效值(原始或填充后)和上一次的滚动均值,实现递推计算

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:35:22