一、一个非常真实的使用场景
假设你在做检测评测统计,有如下数据:
| class | part1 | TP | FP | FN | GT_count |
|---|---|---|---|---|---|
| cow | v01 | 5 | 1 | 0 | 6 |
| cow | v01 | 4 | 0 | 1 | 5 |
| dog | v02 | 3 | 2 | 1 | 4 |
目标是:
按 class + part1 统计 TP / FP / FN / GT 数量
二、第一种写法:很多人最常用,但最容易踩坑
groupby_df = df.groupby(['class', 'part1']).agg(
{'TP': 'sum', 'FP': 'sum', 'FN': 'sum', 'GT_count': 'sum'}
)
这段代码有问题吗?
没有。
但它返回的结果结构是:
class 和 part1 变成了 MultiIndex统计结果才是列也就是说,你拿到的是一张 多级索引 DataFrame。
MultiIndex 在工程中会带来什么问题?
以下问题你大概率都会遇到:
导出 Excel 前必须 reset_index()和其他表 merge 时经常报错新同事很难快速理解数据结构后面再算指标时代码变得很别扭???? 分析阶段还能接受,工程阶段非常痛苦
三、第二种写法:Pandas 官方推荐(强烈建议)
groupby_df = (
df.groupby(['class', 'part1'], as_index=False)
.agg(
TP=('TP', 'sum'),
FP=('FP', 'sum'),
FN=('FN', 'sum'),
GT=('GT_count', 'sum'),
)
)
返回结果是什么样?
分组字段是普通列没有 MultiIndex看起来就是一张“标准统计表”class | part1 | TP | FP | FN | GT
四、两种写法的核心区别对比
| 对比点 | 第一种写法 | 第二种写法 |
|---|---|---|
| 分组字段位置 | Index | 普通列 |
| 索引类型 | MultiIndex | 普通 Index |
| 是否需要 reset_index | 是 | 否 |
| 列名是否可控 | 否 | 是 |
| 扩展复杂统计 | 不优雅 | 非常自然 |
| 工程实用性 | 较低 | 很高 |
五、真实项目中的差距会越来越大
当统计需求升级,比如你还想算:
平均置信度唯一 track 数第一种写法会越来越臃肿:
df.groupby(['class', 'part1']).agg({
'TP': 'sum',
'FP': 'sum',
'FN': 'sum',
'score': 'mean',
'track_id': 'nunique'
})
而第二种写法依然清晰:
df.groupby(['class', 'part1'], as_index=False).agg(
TP=('TP', 'sum'),
FP=('FP', 'sum'),
FN=('FN', 'sum'),
avg_score=('score', 'mean'),
track_cnt=('track_id', 'nunique'),
)
到此这篇关于Pandas中groupby+agg的两种写法区别小结的文章就介绍到这了,更多相关Pandas中groupby+agg 内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
