如何在pd.groupby()中补全缺失年份并实现数值插值?
按ID分组补全年份并插值的Pandas实现
问题描述
现有包含5年间隔记录的DataFrame,需要按id列分组,补全每组首尾年份之间的缺失年份,并对val列执行线性插值。已知需结合groupby()、set_index()和interpolate()方法,但无法在全局DataFrame上实现该逻辑。
示例数据
输入代码
import pandas as pd data = { 'id': ['a', 'b', 'a', 'b'], 'year': [2005, 2005, 2010, 2010], 'val': [0, 0, 100, 100], } df = pd.DataFrame.from_dict(data)
输入DataFrame
id year val 0 a 2005 0 1 b 2005 0 2 a 2010 100 3 b 2010 100
期望输出
id year val type 0 a 2005 0 original 1 a 2006 20 interpolated 2 a 2007 40 interpolated 3 a 2008 60 interpolated 4 a 2009 80 interpolated 5 a 2010 100 original 6 b 2005 0 original 7 b 2006 20 interpolated 8 b 2007 40 interpolated 9 b 2008 60 interpolated 10 b 2009 80 interpolated 11 b 2010 100 original
注:
type列仅作说明,非必需。
解决方案
通过groupby分组后对每个子组单独处理,补全年份序列并执行插值,最后合并所有分组结果:
import pandas as pd data = { 'id': ['a', 'b', 'a', 'b'], 'year': [2005, 2005, 2010, 2010], 'val': [0, 0, 100, 100], } df = pd.DataFrame.from_dict(data) def process_group(group): # 确保分组内年份有序 group_sorted = group.sort_values('year') # 生成该分组的完整年份序列 full_year_range = pd.Series( range(group_sorted['year'].min(), group_sorted['year'].max() + 1), name='year' ) # 合并年份序列与原分组数据,补全缺失行 merged = pd.merge(full_year_range, group_sorted, on='year', how='left') # 填充分组内统一的id值 merged['id'] = group_sorted['id'].iloc[0] # 对val列执行线性插值 merged['val'] = merged['val'].interpolate(method='linear') # 可选:添加原始/插值数据标记列 merged['type'] = merged['val'].isin(group_sorted['val']).map({ True: 'original', False: 'interpolated' }) return merged # 分组处理后合并结果,重置索引 result = df.groupby('id').apply(process_group).reset_index(drop=True) print(result)
代码说明
- 分组处理逻辑:
groupby('id').apply()会将每个id对应的子组传入自定义函数,保证每个分组独立处理 - 补全年份:通过
range()生成从分组最小年份到最大年份的连续序列,再用pd.merge合并原数据,自动生成缺失年份的空行 - 插值实现:
interpolate(method='linear')对val列的缺失值执行线性插值,因年份连续,刚好得到均匀递增的结果 - 可选标记:通过判断
val是否属于原分组的原始值,区分原始数据和插值数据
内容的提问来源于stack exchange,提问作者Geom
相关产品推荐
相关产品推荐

