如何用通用函数在Pandas中复制最近年份行补全缺失观测?
Pandas通用补全缺失年份观测的函数实现
问题描述
给定以下数据集:
import numpy as np import pandas as pd d = {'name': ['a', 'a', 'a'], 'year': [2000, 2001, 2002], 'value': [10, 17, 22] } data_frame = pd.DataFrame(data=d) d1 = {'name': ['a', 'a', 'a'], 'year': [2001, 2002, 2003], 'value': [10, 17, 22] } data_frame1 = pd.DataFrame(data=d1) d2 = {'name': ['a', 'a', 'a'], 'year': [2000, 2002, 2003], 'value': [10, 17, 22] } data_frame2 = pd.DataFrame(data=d2)
需要完成以下补全操作:
data_frame缺失2003年观测:复制2002年(最近可用年份)的行,追加后将年份替换为2003data_frame1缺失2000年观测:复制2001年的行,追加后将年份替换为2000data_frame2缺失2001年观测:复制最早可用年份(2000年)的行,追加后将年份替换为2001
需要编写通用函数实现上述逻辑,无需逐个检查每个DataFrame。
通用函数实现
函数逻辑说明
- 传入目标完整年份范围,明确需要覆盖的所有年份
- 识别当前DataFrame中缺失的年份
- 针对每个缺失年份按规则选择复制行:
- 缺失年份大于现有最大年份:复制现有最大年份的行
- 缺失年份小于现有最小年份:复制现有最小年份的行
- 缺失年份在现有年份区间内:复制现有最早年份的行
- 修改复制行的年份为缺失年份,追加到原DataFrame后按年份排序
代码实现
def fill_missing_years(df, full_year_range): existing_years = set(df['year']) missing_years = [year for year in full_year_range if year not in existing_years] for year in missing_years: min_year = df['year'].min() max_year = df['year'].max() # 选择要复制的基准行 if year > max_year: copy_row = df[df['year'] == max_year].iloc[0].copy() elif year < min_year: copy_row = df[df['year'] == min_year].iloc[0].copy() else: copy_row = df[df['year'] == min_year].iloc[0].copy() # 更新年份并追加到DataFrame copy_row['year'] = year df = pd.concat([df, pd.DataFrame([copy_row])], ignore_index=True) # 按年份排序并重置索引 return df.sort_values('year').reset_index(drop=True)
函数测试
定义完整年份范围
full_years = [2000, 2001, 2002, 2003]
处理各DataFrame
# 补全data_frame filled_df = fill_missing_years(data_frame, full_years) print("补全后的data_frame:") print(filled_df) # 补全data_frame1 filled_df1 = fill_missing_years(data_frame1, full_years) print("\n补全后的data_frame1:") print(filled_df1) # 补全data_frame2 filled_df2 = fill_missing_years(data_frame2, full_years) print("\n补全后的data_frame2:") print(filled_df2)
输出结果
补全后的data_frame: name year value 0 a 2000 10 1 a 2001 17 2 a 2002 22 3 a 2003 22 补全后的data_frame1: name year value 0 a 2000 10 1 a 2001 10 2 a 2002 17 3 a 2003 22 补全后的data_frame2: name year value 0 a 2000 10 1 a 2001 10 2 a 2002 17 3 a 2003 22
扩展说明
如果需要调整中间缺失年份的补全规则(比如取最近的前后年份而非最早年份),只需修改函数中else分支的逻辑即可,灵活性较强。
内容的提问来源于stack exchange,提问作者Avto Abashishvili
相关产品推荐
相关产品推荐

