如何在Pandas中按分组计算失败占比(类SQL分组统计逻辑)
如何在Pandas中按分组计算失败占比(类SQL分组统计逻辑)
嗨,完全可以直接在Pandas里实现这个需求,不需要中间DataFrame或者手动循环分组,用groupby结合聚合操作就能搞定,而且效率很高!
先看看你给出的原始DataFrame:
| ts | tenant | result |
|---|---|---|
| 1 | t1 | pass |
| 1 | t1 | pass |
| 1 | t2 | pass |
| 2 | t1 | fail |
| 2 | t1 | fail |
| 2 | t2 | fail |
| 2 | t1 | pass |
| 2 | t2 | pass |
| 3 | t1 | pass |
| 3 | t1 | pass |
| 3 | t2 | pass |
你想要实现的SQL逻辑是这样的:
select ts, tenant, count(case result when 'fail' then 1 else 0) / count(1) as fail_ratio from tbl group by ts, tenant
最终要得到的目标结果:
| ts | tenant | fail_ratio |
|---|---|---|
| 1 | t1 | 0.0 |
| 1 | t2 | 0.0 |
| 2 | t1 | 0.666 |
| 2 | t2 | 0.5 |
| 3 | t1 | 0.0 |
| 3 | t2 | 0.0 |
下面给你两种简单的实现方式:
方法一:简洁的一步式计算
利用Pandas的布尔值求和特性(True会被视为1,False视为0),直接在分组聚合时计算失败数与总数的比值:
import pandas as pd # 先构造你的示例数据(如果已经有DataFrame可以跳过这步) df = pd.DataFrame({ 'ts': [1,1,1,2,2,2,2,2,3,3,3], 'tenant': ['t1','t1','t2','t1','t1','t2','t1','t2','t1','t1','t2'], 'result': ['pass','pass','pass','fail','fail','fail','pass','pass','pass','pass','pass'] }) # 核心代码:分组后计算失败占比 fail_ratio_df = df.groupby(['ts', 'tenant'])['result'].agg( fail_ratio=lambda x: (x == 'fail').sum() / len(x) ).reset_index() # 查看结果 print(fail_ratio_df)
方法二:分步计算(更易理解)
如果觉得一步式有点抽象,可以拆分步骤,先计算每组的失败数和总记录数,再求比值,逻辑更清晰:
# 分组计算失败数和总记录数 grouped_stats = df.groupby(['ts', 'tenant'])['result'].agg( fail_count=lambda x: (x == 'fail').sum(), total_count='count' ).reset_index() # 计算失败占比 grouped_stats['fail_ratio'] = grouped_stats['fail_count'] / grouped_stats['total_count'] # 保留需要的列(可选) fail_ratio_df = grouped_stats[['ts', 'tenant', 'fail_ratio']]
这两种方法都是Pandas的矢量化操作,比手动循环分组高效得多,完全不需要额外的中间表。得到的fail_ratio_df就是你想要的结果,直接可以用来做时间序列绘图——比如用matplotlib或者seaborn按tenant分组,绘制ts与fail_ratio的折线图就行。
备注:内容来源于stack exchange,提问作者Mr T.
相关产品推荐
相关产品推荐

