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

如何为已有的Pandas GroupBy对象添加分组层级以优化性能?

解决方案:复用基础分组结果以减少耗时

两次独立执行groupby的核心问题在于,pandas会重复对col1/col2/col3进行哈希计算、排序等分组前置操作,这在大型DataFrame上会产生极高的冗余开销。以下是两种可行的复用方案:

方法一:预计算基础分组标识列

通过给每个(col1, col2, col3)组合分配唯一ID,只计算一次基础分组的哈希,后续分组直接复用该ID:

import pandas as pd

# 预计算基础分组的唯一整数ID(仅执行一次col1-col3的分组计算)
df['base_group_id'] = df.groupby(["col1", "col2", "col3"]).ngroup()

# 第一次分组(执行你的聚合操作,比如sum/mean等)
dfNew1 = df.groupby(["col1", "col2", "col3"], as_index=False).agg(
    # 示例聚合:计算col5的均值,col6的总和
    col5_mean=('col5', 'mean'),
    col6_sum=('col6', 'sum')
)

# 第二次分组:复用基础分组结果,避免重复计算col1-col3
# 添加sort=False跳过排序操作,进一步减少耗时
dfNew2 = df.groupby(["col1", "col2", "col3", "col4"], as_index=False, sort=False).agg(
    col5_mean=('col5', 'mean'),
    col6_sum=('col6', 'sum')
)
# 若不需要base_group_id,后续可直接删除:df.drop('base_group_id', axis=1, inplace=True)

方法二:遍历基础分组的子DataFrame

直接复用第一次分组得到的子数据集,在每个子集中单独按col4分组:

baseGrouper = df.groupby(["col1", "col2", "col3"])

# 第一次分组的聚合结果
dfNew1 = baseGrouper.agg(
    col5_mean=('col5', 'mean'),
    col6_sum=('col6', 'sum')
).reset_index()

# 第二次分组:遍历每个基础分组,内部按col4聚合
sub_group_results = []
for group_keys, sub_df in baseGrouper:
    # 子数据集内按col4分组
    sub_result = sub_df.groupby("col4", as_index=False).agg(
        col5_mean=('col5', 'mean'),
        col6_sum=('col6', 'sum')
    )
    # 补回col1-col3的分组键信息
    sub_result[["col1", "col2", "col3"]] = group_keys
    sub_group_results.append(sub_result)

# 合并所有子分组结果
dfNew2 = pd.concat(sub_group_results, ignore_index=True)

关键注意事项

  • 务必明确聚合操作:仅创建GroupBy对象不会触发实际分组计算,耗时发生在agg()/apply()等执行阶段。
  • 大型数据集优先用方法一:方法二在基础分组数量极多时,遍历会产生额外开销;方法一的ngroup()是矢量化操作,效率更高。

内容的提问来源于stack exchange,提问作者Philip Kahn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 23:35:18