Python DataFrame高效批量计算多列年度增长率的方法
高效实现方案
你当前手动逐列编码的方式在列数增多时维护成本极高,且容易出现手误漏算,以下两种通用实现方式无需手动枚举列,适配任意年份数、任意指标数量的场景。
方法1:长表转换法(通用性最强,推荐)
核心逻辑是先把宽表转为长结构,按主体、指标分组后直接调用pandas内置的增长率计算函数,最后转回你需要的宽表格式。
import pandas as pd # 复现你的测试数据集 data = pd.DataFrame({ 'Subject': [1,2,3], '2000_X1': [100,95,110], '2000_X2': [50,40,45], '2001_X1': [120,100,100], '2001_X2': [45,45,45], '2002_X1': [110,105,110], '2002_X2': [50,50,40] }) # 1. 宽转长,拆分年份和指标字段 long_df = data.melt(id_vars='Subject', var_name='col_raw', value_name='val') long_df[['year', 'metric']] = long_df['col_raw'].str.split('_', expand=True) long_df['year'] = long_df['year'].astype(int) # 2. 分组排序后计算同比增长率 long_df = long_df.sort_values(['Subject', 'metric', 'year']) long_df['growth'] = long_df.groupby(['Subject', 'metric'])['val'].pct_change() # 3. 增长率结果转回宽表,拼接回原数据 gro_df = long_df.dropna(subset=['growth']).pivot(index='Subject', columns=['year','metric'], values='growth') gro_df.columns = [f'{y}_{m}_gro' for y,m in gro_df.columns] final_data = data.merge(gro_df.reset_index(), on='Subject')
运行后final_data的输出和你给出的期望结果完全一致,后续新增年份、新增X系列指标时无需修改任何代码。
方法2:宽表直接遍历法(无需转换表结构)
如果你不想改变原有表的处理逻辑,可以直接按规则提取列名分组,循环计算即可:
from collections import defaultdict # 提取所有指标列,按指标名分组 metric_col_group = defaultdict(list) for col in data.columns: if col == 'Subject': continue year_str, metric_name = col.split('_') metric_col_group[metric_name].append( (int(year_str), col) ) # 逐指标按年份顺序计算增长率 for metric, year_col_pair in metric_col_group.items(): year_col_pair.sort() # 按年份升序排列 for idx in range(1, len(year_col_pair)): prev_year, prev_col = year_col_pair[idx-1] curr_year, curr_col = year_col_pair[idx] gro_col_name = f'{curr_year}_{metric}_gro' data[gro_col_name] = (data[curr_col] - data[prev_col]) / data[prev_col]
计算结果和手动编码、方法1的结果完全一致。
补充说明
- 如果数据集存在缺失值,
pct_change()会自动在对应位置返回空值,和手动计算的逻辑保持一致 - 如果需要计算定基增长率(比如所有年份都和2000年基准值比),只需要把分组后的计算逻辑改成
long_df['val'] / long_df.groupby(['Subject','metric'])['val'].transform('first') - 1即可
内容的提问来源于stack exchange,提问作者undernoob
相关产品推荐
相关产品推荐

