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

含缺失值的多级分组滚动平均计算:缺失行补0方案求助

问题解答

关于多级索引上采样的问题

是的,直接通过resample('1M', level=0)对包含datetime的多级索引做上采样是不被支持的——resample要求索引必须是单一的datetime类型索引,或者你先将datetime列设为唯一索引后再操作,不能直接指定多级索引中的某一层来做上采样。

可行解决方案(支持任意分组数量)

核心思路是先为每个分组补全所有缺失的月度行并将N填充为0,再基于补全后的完整数据计算滚动平均,确保边界位置无法计算的结果为np.nan。

步骤1:确保日期列格式正确

首先确认month列是datetime类型,如果是字符串格式先转换:

import pandas as pd
import numpy as np

# 转换month列为datetime(根据实际格式调整format参数)
df['month'] = pd.to_datetime(df['month'], format='%Y-%m')

步骤2:补全每个分组的缺失月度数据

生成每个分组的完整月度时间序列,将缺失月份的N填充为0:

# 获取全局时间范围(从数据最早到最晚的月份)
all_months = pd.date_range(start=df['month'].min(), end=df['month'].max(), freq='M')

# 为每个分组生成完整的月度索引,并合并原始数据
full_df = (
    df.groupby(['from', 'to', 'subset'])
    .apply(lambda g: g.set_index('month').reindex(all_months, fill_value=0).reset_index())
    .rename(columns={'index': 'month'})
    .reset_index(drop=True)
)

这里用groupby.apply为每个分组单独补全缺失月份,reindex自动填充N为0,适合任意数量的分组列。

步骤3:计算3期中心滚动平均

在补全后的数据集上,按分组计算滚动平均,设置min_periods=3确保只有凑够3期(包括补的0)才返回有效值,边界位置自动为np.nan:

# 计算滚动平均并添加到结果中
full_df['rolling_avg'] = full_df.groupby(['from', 'to', 'subset'])['N'].transform(
    lambda x: x.rolling(window=3, center=True, min_periods=3).mean()
)

替代方案:用透视表简化操作

如果分组列较多,也可以用透视表生成宽表后计算滚动平均,再转回长格式:

# 生成月度-分组的透视表,缺失值填充为0
pivot_df = df.pivot_table(
    index='month', 
    columns=['from', 'to', 'subset'], 
    values='N', 
    fill_value=0
)

# 对每个分组列计算滚动平均
rolling_result = pivot_df.rolling(window=3, center=True, min_periods=3).mean()

# 转回长格式,得到最终结果
final_df = rolling_result.unstack().reset_index().rename(columns={0: 'rolling_avg'})
# 可选:合并原始N值
final_df = final_df.merge(full_df[['month', 'from', 'to', 'subset', 'N']], on=['month', 'from', 'to', 'subset'], how='left')

结果说明

  • 所有原本缺失的月度行已被补全,N值为0
  • 滚动平均仅在有完整3期数据的位置计算,首尾两个月(边界)的rolling_avg为np.nan
  • 方案支持任意数量的分组列,只需修改groupby或columns中的分组字段即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:52:47