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

