如何在Pandas中计算分组占比?求慢代码优化方案
提速Pandas分组占比计算的实用方法
嗨,我明白你现在遇到的问题——用lambda配合transform计算分组内占比时速度拖后腿,这确实是因为自定义lambda函数会带来额外的调用开销,而且没利用到Pandas内置的向量化优化。下面给你几个高效的替代方案,亲测速度提升明显:
方案一:利用分组总和+广播除法(最快推荐)
这种方法直接借助Pandas的索引对齐和广播机制,跳过transform的中间步骤,完全用向量化操作完成计算:
import pandas as pd # 生成示例数据(和你的代码一致) index = pd.MultiIndex.from_product([('a', 'b'), ('alpha', 'beta'), ('hello', 'world')], names=['i0', 'i1', 'i2']) df = pd.DataFrame([[1, 2], [3, 4], [5, 6], [7, 8], [1, 2], [3, 4], [5, 6], [7, 8]], index=index, columns=['A', 'B']) # 定义分组键(这里按i0和i1分组,你可以根据实际需求调整) group_keys = ['i0', 'i1'] # 第一步:计算每组的总和 group_totals = df.groupby(group_keys).sum() # 第二步:直接用div做广播除法,Pandas会自动对齐索引 df_ratio = df.div(group_totals, level=group_keys) print(df_ratio)
方案二:用内置聚合函数替代lambda的transform
如果习惯用transform,也可以抛弃自定义lambda,直接传入内置的'sum'参数,Pandas内部会用优化后的C级代码执行,比lambda快得多:
df_ratio = df / df.groupby(group_keys).transform('sum')
为什么原来的方法慢?
- 自定义
lambda函数在transform中会被逐组调用,每一次调用都有Python层面的开销,而内置聚合函数是用底层优化实现的,效率差几个数量级。 - 方案一的广播除法直接利用了Pandas的索引对齐特性,避免了
transform过程中生成中间临时数据的额外消耗。
你可以用%timeit测试一下这几种方法的速度差异,绝对能看到明显的提升!
内容的提问来源于stack exchange,提问作者Ginger
相关产品推荐
相关产品推荐

