You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:36:09