如何将Pandas GroupBy多索引结果打包为元组并简化输出
解决方案
一、替代agg中lambda计算的高效简洁方式
针对大型DataFrame,使用numpy的向量化函数比纯Python lambda更高效,能显著提升运算速度。可以用以下几种方式简化:
方式1:复用自定义函数
定义一个可复用的聚合函数,避免重复编写lambda:
import numpy as np def pct_mean_round(x): return np.round(100 * x.mean(), 0).astype(int) # 调用时直接传入函数名 agg_result = df_3[filter_3].groupby(grpby_3).agg( {'AOT in Cases': pct_mean_round, 'COT by ME (1.3.2)': pct_mean_round} )
方式2:简化lambda写法
如果不想额外定义函数,用numpy的np.round替代Python内置round,速度更快:
agg_dict = { 'AOT in Cases': lambda x: np.round(100 * x.mean(), 0), 'COT by ME (1.3.2)': lambda x: np.round(100 * x.mean(), 0) } agg_result = df_3[filter_3].groupby(grpby_3).agg(agg_dict)
方式3:批量处理多列
如果需要处理的列很多,用字典推导式批量生成聚合规则:
target_cols = ['AOT in Cases', 'COT by ME (1.3.2)'] agg_dict = {col: lambda x: np.round(100 * x.mean(), 0) for col in target_cols} agg_result = df_3[filter_3].groupby(grpby_3).agg(agg_dict)
numpy的向量化操作避免了Python级别的循环,在处理大型数据集时优势明显。
二、将季度值打包为元组并去除Quarter列
方法1:先unstack再后续处理(直观易维护)
先按原逻辑生成多索引结果,再对列按指标分组打包:
# 生成多索引列的结果 multi_idx_result = agg_result.unstack('Quarter') # 按列的第一层索引(指标名)分组,将对应季度值打包为元组 final_result = multi_idx_result.groupby(level=0, axis=1).apply(tuple)
处理后final_result的列就是两个指标名,每个单元格是对应各季度值的元组,顺序与Quarter的自然排序一致。
方法2:单条groupby语句直接实现
如果想要一步到位,先排除Quarter作为分组键,聚合时按Quarter分组计算后打包:
# 提取除Quarter外的分组键 group_keys = [k for k in grpby_3 if k != 'Quarter'] # 提前固定Quarter的顺序,避免元组内值的顺序混乱 sorted_quarters = sorted(df_3[filter_3]['Quarter'].unique()) final_result = df_3[filter_3].groupby(group_keys).agg( { 'AOT in Cases': lambda x: tuple( np.round(100 * x[df_3[filter_3]['Quarter'] == q].mean(), 0) for q in sorted_quarters ), 'COT by ME (1.3.2)': lambda x: tuple( np.round(100 * x[df_3[filter_3]['Quarter'] == q].mean(), 0) for q in sorted_quarters ) } )
这种方式直接得到目标结果,但需提前确认Quarter的顺序,保证元组内值的一致性。
内容的提问来源于stack exchange,提问作者Rajib Lochan Sarkar
相关产品推荐
相关产品推荐

