pandas groupby计数后如何遍历索引值对调用自定义函数
问题背景
现有如下结构的pandas DataFrame:
import pandas as pd df = pd.DataFrame({'Category': [1, 1, 2, 3, 2, 1], 'Value': [20, 10, 5, 15, 20, 5]})
DataFrame内容如下:
| 索引 | Category | Value |
|---|---|---|
| 0 | 1 | 20 |
| 1 | 1 | 10 |
| 2 | 2 | 5 |
| 3 | 3 | 15 |
| 4 | 2 | 20 |
| 5 | 1 | 5 |
需求为统计每个Category对应的条目数量,遍历统计结果调用自定义emit_metric函数上报指标。当前通过如下代码获取分组计数结果:
df_grouped_by_category = df.groupby("Category").count()
得到的计数结果为:
1 3 2 2 3 1
对聚合结果应用函数上报时,以下两种写法均无法识别列名,运行报错:
# 错误写法1 df_grouped_by_category.apply(lambda x: self.emit_metric(x.category, x.count)) # 错误写法2 df_grouped_by_category.apply(lambda x: self.emit_metric(x["Category"], x["count"])) # 自定义指标上报函数 def emit_metric(category, count) -> None: # 指标上报相关逻辑代码 pass
错误原因
- 执行
df.groupby("Category").count()聚合后,Category会从普通列转为DataFrame的行索引,无法通过x["Category"]的列索引方式取值 - 聚合后仅保留原
Value列存储计数结果,不存在名为count的列;代码中写的x.count是pandas对象内置的计数方法,不是统计得到的条目数值 - DataFrame的
apply方法默认按列遍历(参数axis=0),未指定轴向的情况下无法逐行拿到单组的分类和计数值
正确实现方案
方案1:重置索引后按行调用apply
分组计数时关闭索引自动生成,将计数结果列重命名为count,指定axis=1按行遍历:
df_grouped = df.groupby("Category", as_index=False)["Value"].count().rename(columns={"Value": "count"}) df_grouped.apply(lambda x: self.emit_metric(x["Category"], x["count"]), axis=1)
方案2:直接遍历groupby对象
无需提前生成聚合DataFrame,遍历分组对象时直接取分组键和组内条目数,代码可读性更高:
for category, group in df.groupby("Category"): count = len(group) self.emit_metric(category, count)
方案3:用size()生成计数Series后遍历
size()会返回带分组索引的计数Series,直接遍历键值对即可:
category_count = df.groupby("Category").size() for category, count in category_count.items(): self.emit_metric(category, count)
优先选择方案2或方案3,无需处理apply轴向参数,代码逻辑更直观,遍历性能也优于apply按行执行。
内容的提问来源于stack exchange,提问作者Raquel
相关产品推荐
相关产品推荐

