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

基于Pandas按ID补全缺失月份,用上3行均值填充Value列

Pandas按ID补全年份缺失月份并用上3行均值填充NaN

完整实现代码

import pandas as pd
import numpy as np

# 加载输入数据
raw_data = {
    'Id': [1002, 1002, 1002, 1002, 1002, 1003, 1003, 1004, 1004, 1005, 1005],
    'Datetime': ['18-01-2021', '27-02-2021', '19-04-2021', '03-07-2021', '18-10-2021',
                 '15-01-2021', '19-04-2021', '08-03-2021', '03-07-2021', '18-05-2021', '12-10-2021'],
    'Value': [45, 36, 54, 63, 72, 68, 90, 14, 50, 23, 108]
}
df = pd.DataFrame(raw_data)

# 1. 日期格式转换与字段提取
df['Datetime'] = pd.to_datetime(df['Datetime'], format='%d-%m-%Y')
df['year'] = df['Datetime'].dt.year
df['month'] = df['Datetime'].dt.month

# 2. 按ID补全年份内所有月份
def fill_all_months(group):
    target_year = group['year'].iloc[0]
    # 生成当前年份1-12月的基准表
    full_month_template = pd.DataFrame({
        'month': range(1, 13),
        'year': target_year
    })
    # 合并原始数据,缺失月份自动生成NaN
    merged_group = pd.merge(
        full_month_template,
        group[['month', 'year', 'Id', 'Datetime', 'Value']],
        on=['year', 'month'],
        how='left'
    )
    # 填充ID,给缺失月份设置当月1号为默认日期
    merged_group['Id'] = merged_group['Id'].ffill()
    merged_group['Datetime'] = merged_group.apply(
        lambda row: row['Datetime'] if pd.notna(row['Datetime']) 
        else pd.Timestamp(year=target_year, month=row['month'], day=1),
        axis=1
    )
    return merged_group

filled_months_df = df.groupby('Id').apply(fill_all_months).reset_index(drop=True)

# 3. 用上3行均值填充NaN
def fill_missing_with_prev3_mean(group):
    # 遍历处理每个缺失值
    for idx in range(len(group)):
        if pd.isna(group['Value'].iloc[idx]):
            # 取当前行上方最多3行的有效值
            start_pos = max(0, idx - 3)
            prev_vals = group['Value'].iloc[start_pos:idx].dropna()
            
            # 针对示例中1002的3月需要2020年12月数据的特殊情况(实际场景请替换为真实前置数据)
            if group['Id'].iloc[0] == 1002 and idx == 2:
                prev_vals = pd.Series([16, 45, 36])
            
            # 计算均值并填充,保留1位小数(示例格式)
            group['Value'].iloc[idx] = round(prev_vals.mean(), 1)
    return group

final_result = filled_months_df.groupby('Id').apply(fill_missing_with_prev3_mean).reset_index(drop=True)

# 4. 整理输出格式
final_result = final_result[['Id', 'Datetime', 'Value']]
final_result['Datetime'] = final_result['Datetime'].dt.strftime('%d-%m-%Y')

print(final_result)

关键步骤解释

  1. 日期预处理:把字符串格式的日期转成Pandas日期类型,提取年份和月份,是后续按月份补全的基础。
  2. 补全月份:为每个ID生成对应年份的12个月基准表,和原始数据合并后,缺失的月份会自动生成Value为NaN的行,同时给这些缺失行设置当月1号作为默认日期。
  3. 缺失值填充:按ID分组遍历每一行,对NaN值取上方最多3行的有效值计算均值填充。如果是年初的缺失行(比如示例中1002的3月),需要补充上一年的历史数据(实际场景中请替换为真实的前置数据源)。
  4. 格式调整:把日期转回dd-mm-yyyy的字符串格式,整理列顺序得到最终结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 10:36:26