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

如何高效实现Pandas DataFrame多列多维度聚合与宽表转换?

高效实现Pandas DataFrame的多维度聚合与列重塑

嘿,我来帮你简化这个数据整理的流程!你之前多次创建pivot再合并的方式确实有点重复繁琐,其实我们可以用一次分组聚合+列名重塑的方式搞定,代码更简洁,运行效率也更高。

核心实现方法(推荐)

这种方法通过pivot_table一次性完成年度维度的聚合,再合并全局统计结果,步骤清晰且高效:

import pandas as pd

# 你的原始数据
data = {'id':[101,101,101,101,102,102,102,102], 'day':[1,2,1,2,1,2,1,2], 'year':[2011,2011,2012,2012,2011,2011,2012,2012], 'avg':[0.500,0.400,0.300,0.200,0.555,0.455,0.355,0.255], 'sum':[1, 2, 2, 3, 6, 6, 8, 9], 'div':[2, 1, 3, 2, 6, 1, 6, 3]}
df = pd.DataFrame(data)

# 1. 计算每个id的全局sum和div总和
global_stats = df.groupby('id')[['sum', 'div']].sum().reset_index()

# 2. 按id+year聚合,针对不同列设置对应聚合规则
yearly_stats = df.pivot_table(
    index='id',
    columns='year',
    aggfunc={
        'avg': 'mean',   # 按年份计算avg的平均值
        'sum': 'sum',    # 按年份计算sum的总和
        'div': 'mean'    # 按年份计算div的平均值(可根据需求调整)
    }
)

# 3. 重塑列名为「年份_列名」格式
yearly_stats.columns = [f'{year}_{col}' for col, year in yearly_stats.columns]

# 4. 合并结果并调整列顺序
result = global_stats.merge(yearly_stats, on='id')[
    ['id', 'sum', 'div', '2011_avg', '2012_avg', '2011_sum', '2012_sum', '2011_div', '2012_div']
]

print(result)

运行后输出:

id  sum  div  2011_avg  2012_avg  2011_sum  2012_sum  2011_div  2012_div
0  101    8    8      0.45      0.25         3         5       1.5       2.5
1  102   29   16     0.505     0.305        12        17       3.5       4.5

注:如果你的div列需要其他聚合规则(比如取特定day的值、总和等),只需要修改aggfunc中div对应的函数即可,灵活性很强。

更紧凑的写法(一次groupby搞定)

如果你想把所有聚合逻辑放在一次操作里,可以用groupby+agg结合嵌套展开的方式:

import pandas as pd

data = {'id':[101,101,101,101,102,102,102,102], 'day':[1,2,1,2,1,2,1,2], 'year':[2011,2011,2012,2012,2011,2011,2012,2012], 'avg':[0.500,0.400,0.300,0.200,0.555,0.455,0.355,0.255], 'sum':[1, 2, 2, 3, 6, 6, 8, 9], 'div':[2, 1, 3, 2, 6, 1, 6, 3]}
df = pd.DataFrame(data)

# 一次完成全局+年度聚合
agg_result = df.groupby('id').agg(
    sum=('sum', 'sum'),
    div=('div', 'sum'),
    avg_year=('avg', lambda x: x.groupby(df['year']).mean()),
    sum_year=('sum', lambda x: x.groupby(df['year']).sum()),
    div_year=('div', lambda x: x.groupby(df['year']).mean())
)

# 展开嵌套的年度统计列并命名
agg_result = agg_result.join(
    pd.concat(
        [agg_result[col].apply(pd.Series) for col in ['avg_year', 'sum_year', 'div_year']],
        axis=1
    )
).drop(['avg_year', 'sum_year', 'div_year'], axis=1)

agg_result.columns = ['sum', 'div', '2011_avg', '2012_avg', '2011_sum', '2012_sum', '2011_div', '2012_div']
agg_result.reset_index(inplace=True)

print(agg_result)

这两种方法都避免了多次pivot和合并的冗余操作,在数据量较大时能显著提升运行效率,代码也更易维护。

内容的提问来源于stack exchange,提问作者YilGuk Seo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:40:05