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

如何调整groupby+unstack的列名?兼顾性能与列名可读性

解决Groupby+Unstack后的多层列名问题

首先我注意到你原来的groupby代码里有个小笔误——你在agg里写的是tuning_hours,但样本数据里的目标字段是watch_hours,先修正这个细节,然后我们来搞定列名的问题。

最优方案:简化聚合写法,直接得到规范列名

你之所以会得到多层列名,是因为用了agg({'watch_hours':['sum']})这种字典+列表的聚合写法,它会生成包含字段名、聚合函数名的多层索引。其实如果只需要对watch_hours求和,完全可以简化写法,这样unstack之后直接就能得到和pivot_table一样的规范列名,同时保留groupby的高性能:

# 优化后的Groupby方案,性能不变,列名和pivot_table一致
df_grouped = df_tier.groupby(['device_id', 'net_grp'])['watch_hours'].sum()
result = df_grouped.unstack(level='net_grp').fillna(0).reset_index()

执行这段代码后,结果的列名就是各个net_grp的取值(比如TCH、NJV、SHX等),和pivot_table输出的列格式完全一致,而且性能和你之前测试的15ms差不多,甚至可能更快——因为减少了多层索引的生成开销。

备选方案:处理已生成的多层列名

如果因为业务需求,你必须保留原来的字典式聚合写法(比如需要同时执行多个聚合操作),可以通过修改MultiIndex列名来提取net_grp的取值:

# 修正笔误后的原Groupby代码
result = df_tier.groupby(['device_id','net_grp']).agg({'watch_hours':['sum']}).unstack(level='net_grp').fillna(0).reset_index()

# 提取多层列索引的最后一层(也就是net_grp的取值)作为列名
result.columns = result.columns.get_level_values(-1)

# 把device_id的列名修正回来(reset_index后它的列名会变成空字符串)
result = result.rename(columns={'': 'device_id'}).set_index('device_id')

这样处理后,列名就只剩下net_grp的各个取值,和pivot_table的输出一致。

为什么这个方案可行?

  • 第一种简化写法直接跳过了多层索引的生成,聚合结果是单层Series,unstack后自然用net_grp的值作为列名,完全符合你的需求。
  • 第二种方法针对已生成的MultiIndex,通过get_level_values(-1)直接取最底层的net_grp值作为列名,再修正device_id的列名即可。

这样你就能在享受groupby高性能的同时,得到和pivot_table一样易用的输出格式了。

内容的提问来源于stack exchange,提问作者Shuvayan Das

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:35:17