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

如何为长格式Pandas DataFrame补全年份内缺失的月份数据?

Pandas补全年度缺失月份记录并填充最近值

问题背景

现有长格式Pandas DataFrame,部分月份数据缺失。需要为每个国家的每一年补全1-12月的记录,缺失月份的total_points、rank等字段沿用最近已有月份的数值,同时rank_date需对应补全后的月份调整日期。

输入示例

country_full    year    month        rank   rank_date   total_points    
Zimbabwe       2021        8         108    2021-08-12  1171.88
Zimbabwe       2021        10        108    2021-09-12  1171.88
Zimbabwe       2022        01        108    2022-01-12  1171.88
Germany        1994        01        10     1994-01-10  1171.88
Germany        1994        02        10     1994-02-09  1327.8
Germany        1994        04        10     1994-04-07  1459.9

期望输出示例

country_full    year    month        rank   rank_date   total_points    
Zimbabwe       2021        8         108    2021-08-12  1171.88
Zimbabwe       2021        9         108    2021-08-12  1171.88
Zimbabwe       2021        10        108    2021-10-12  1171.88
Zimbabwe       2021        11        108    2021-11-12  1171.88
Zimbabwe       2021        12        108    2021-12-12  1171.88
Zimbabwe       2022        01        108    2022-01-12  1171.88
Germany        1994        01        10     1994-01-10  1171.88
Germany        1994        02        10     1994-02-09  1327.8
Germany        1994        03        10     1994-03-09  1459.9
Germany        1994        04        10     1994-04-07  1459.9

实现方法

以下是完整的代码实现步骤:

  1. 数据类型预处理
    先将month转为整数,rank_date转为日期类型,确保后续操作正常:

    import pandas as pd
    
    # 定义原始数据(实际场景可替换为读取文件)
    df = pd.DataFrame({
        'country_full': ['Zimbabwe', 'Zimbabwe', 'Zimbabwe', 'Germany', 'Germany', 'Germany'],
        'year': [2021, 2021, 2022, 1994, 1994, 1994],
        'month': [8, 10, 1, 1, 2, 4],
        'rank': [108, 108, 108, 10, 10, 10],
        'rank_date': ['2021-08-12', '2021-09-12', '2022-01-12', '1994-01-10', '1994-02-09', '1994-04-07'],
        'total_points': [1171.88, 1171.88, 1171.88, 1171.88, 1327.8, 1459.9]
    })
    
    # 转换数据类型
    df['month'] = df['month'].astype(int)
    df['rank_date'] = pd.to_datetime(df['rank_date'])
    
  2. 生成完整月份序列
    按country_full和year分组,为每组生成1到12月的完整月份记录:

    # 创建每组的完整月份索引
    def create_full_months(group):
        year = group['year'].iloc[0]
        country = group['country_full'].iloc[0]
        full_months = pd.DataFrame({
            'country_full': [country]*12,
            'year': [year]*12,
            'month': range(1, 13)
        })
        return full_months
    
    # 对原数据分组并生成完整序列,再合并为新表
    full_df = df.groupby(['country_full', 'year']).apply(create_full_months).reset_index(drop=True)
    
  3. 合并原数据并填充缺失值
    将原数据与完整月份表合并,用向前填充(ffill)补全缺失的字段值,同时调整rank_date的月份:

    # 合并原数据和完整月份表
    merged_df = pd.merge(full_df, df, on=['country_full', 'year', 'month'], how='left')
    
    # 按国家和年份分组,向前填充缺失的rank、total_points等字段
    merged_df = merged_df.groupby(['country_full', 'year']).ffill()
    
    # 调整rank_date的月份为当前行的month值
    merged_df['rank_date'] = merged_df.apply(
        lambda x: x['rank_date'].replace(month=x['month']), axis=1
    )
    
    # 按国家、年份、月份排序,恢复顺序
    merged_df = merged_df.sort_values(['country_full', 'year', 'month']).reset_index(drop=True)
    
  4. 结果整理
    最终得到的merged_df就是补全后的数据集,与期望输出一致。

关键说明

  • ffill():按分组向前填充,确保缺失月份沿用最近已有月份的数值,完全匹配需求。
  • rank_date调整:通过replace方法替换日期中的月份部分,保证日期与当前行的月份匹配。
  • 分组生成完整序列:确保每个国家的每一年都有1-12月的记录,不会遗漏任何月份。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 02:15:41