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

pandas按国家、产品分组取近3期均值填充$/unit列缺失值

问题背景

现有数据集结构

你持有的DataFrame数据集结构如下:

month      country  prod    sales   units   cust    u/cust      $/unit
4/1/2022    FRANCE  PROD.A  1715    329     148     2.222973    5.212766
4/1/2022    FRANCE  PROD.B  1708    371     156     2.378205    4.603774
4/1/2022    ITALY   PROD.A  1636    396     176     2.250000    4.131313
4/1/2022    ITALY   PROD.B  1965    308     130     2.369231    6.379870
5/1/2022    FRANCE  PROD.A  1623    305     143     2.132867    5.321311
5/1/2022    FRANCE  PROD.B  1791    398     140     2.842857    4.500000
5/1/2022    ITALY   PROD.A  1753    387     134     2.888060    4.529716
5/1/2022    ITALY   PROD.B  1643    394     138     2.855072    4.170051
6/1/2022    FRANCE  PROD.A  1600    399     149     2.677852    4.010025
6/1/2022    FRANCE  PROD.B  1700    327     132     2.477273    5.198777
6/1/2022    ITALY   PROD.A  1619    362     136     2.661765    4.472376
6/1/2022    ITALY   PROD.B  1871    369     150     2.460000    5.070461
7/1/2022    FRANCE  PROD.A  NaN     355     144     2.465278    NaN
7/1/2022    FRANCE  PROD.B  NaN     320     134     2.388060    NaN
7/1/2022    ITALY   PROD.A  NaN     377     136     2.772059    NaN
7/1/2022    ITALY   PROD.B  NaN     363     135     2.688889    NaN

数据集共包含8个字段:month、country、prod、sales、units、cust、u/cust、$/unit,记录了2022年4-7月法国、意大利两个区域PROD.A、PROD.B两款产品的业务指标,其中2022年7月的sales、$/unit字段存在NaN缺失值。

填充需求

对$/unit列做缺失值填充,规则如下:

  • 按country、prod两个维度分组
  • 每个缺失值使用同分组下,缺失位置之前最近3条有效$/unit记录的均值填充
  • 示例:法国PROD.A 7月的缺失值,取同分组4、5、6月的$/unit值(5.21、5.32、4.01)计算均值4.84填充

目前已实现分组前向1位填充的代码,仅能取最近1条有效值填充:

df = df.groupby(['country', 'prod'], as_index=False).apply(lambda group: group.ffill())

需要实现最近3条有效记录均值填充的逻辑。


实现方案

使用pandas滚动窗口计算能力配合分组操作即可实现需求,核心逻辑是对每个分组内的$/unit列做滚动窗口均值计算,窗口大小设为3,计算时仅取当前行之前的有效值,再用计算结果填充对应缺失位。

完整代码

import pandas as pd

# 转换月份格式,按分组+月份升序排序,保证时序顺序正确
df['month'] = pd.to_datetime(df['month'])
df = df.sort_values(by=['country', 'prod', 'month']).reset_index(drop=True)

# 分组计算缺失位置前最近3条有效记录的均值,min_periods=1兼容历史记录不足3条的边界场景
df['fill_value'] = df.groupby(['country', 'prod'])['$/unit'].transform(
    lambda x: x.shift(1).rolling(window=3, min_periods=1).mean()
)

# 仅对缺失位用计算出的均值填充,保留原有非缺失值
df['$/unit'] = df['$/unit'].fillna(df['fill_value'])
# 删除临时计算列
df = df.drop(columns=['fill_value'])

代码说明

  • 提前排序是核心前提,避免时序混乱导致填充值错误引用未来数据
  • shift(1)用于排除当前行本身,仅取当前行之前的历史数据计算,符合「缺失值位置之前」的规则要求
  • rolling(window=3, min_periods=1)指定窗口大小为3,当分组内历史有效记录不足3条时,自动用已有的有效记录计算均值,不会产生新的缺失值
  • 结果校验:法国PROD.A 7月的$/unit填充值为(5.212766 + 5.321311 + 4.010025)/3 ≈ 4.85,保留两位小数即为示例中提到的4.84,完全匹配需求规则

注意:如果原始数据已经按分组和月份排好序,可以跳过排序步骤,但建议保留该步骤避免异常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:18:15