如何用Pandas高效按首尾期CAGR批量填充多段NaN值?
用CAGR自动化填充DataFrame中的连续NaN区间
核心思路
通过分组识别连续NaN区间,自动计算每个区间首尾值的复利增长因子,再根据每个NaN在区间内的位置批量完成填充,无需逐段手动处理。
完整实现代码
import pandas as pd import numpy as np # 创建示例数据 data = {'year':[2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020], 'revenue' : [100, np.nan, np.nan, 108, 118, np.nan, np.nan, np.nan, 127, 135]} df = pd.DataFrame(data).set_index('year') # 1. 给每个连续NaN区间+首尾非NaN值分配唯一分组ID df['group'] = df['revenue'].notna().cumsum().ffill() # 2. 计算每个分组的关键信息:起始值、结束值、总年份数 group_metrics = df.groupby('group')['revenue'].agg( start_value='first', end_value='last', total_periods='count' ).reset_index() # 3. 将分组指标合并回原DataFrame df = df.merge(group_metrics, on='group', how='left') # 4. 计算每个数据点在分组内的位置索引(从0开始) df['position'] = df.groupby('group').cumcount() # 5. 计算复利增长因子(对应你公式中省略-1的版本) df['growth_factor'] = (df['end_value'] / df['start_value']) ** (1 / df['total_periods']) # 6. 填充NaN值,非NaN值保持原数据 df['revenue'] = np.where( df['revenue'].isna(), df['start_value'] * (df['growth_factor'] ** df['position']), df['revenue'] ) # 清理辅助列,输出结果 final_df = df.drop(['group', 'start_value', 'end_value', 'total_periods', 'position', 'growth_factor'], axis=1) print(final_df.round(6))
代码步骤说明
- 分组标识:
df['revenue'].notna().cumsum()给每个非NaN值分配递增ID,连续NaN会继承前一个非NaN的ID,自动将需要插值的区间与首尾值归为一组。 - 分组指标计算:通过
groupby获取每个分组的首尾值(对应手动指定的区间端点)和分组总长度(对应你公式中的区间年份数)。 - 位置索引:
cumcount()计算每行在分组内的位置,比如2011是组1的第0位,2012是第1位,对应手动填充时的迭代次数。 - 增长因子计算:严格匹配你给出的CAGR公式,计算每年的复利增长倍数。
- 批量填充:用
np.where批量判断并填充NaN,非NaN值保留原始数据。
此方法支持任意数量的连续NaN区间,完全自动化处理,适配大型数据集。
内容的提问来源于stack exchange,提问作者NigelThornberry7
相关产品推荐
相关产品推荐

