如何提升Pandas groupby中lambda函数的应用效率?
优化Pandas分组统计性能:替代
groupby.apply(lambda)的高效方案 如果你正在处理由小DataFrame重复生成的数据集,需要对分组后的自定义统计量(比如真正例计数)进行计算,groupby.apply(lambda)的性能往往会成为瓶颈——因为它需要逐组调用Python函数,带来额外的运行开销。下面结合你的场景给出更高效的实现方式:
原始场景与慢实现
你的需求是统计每个(col1, col2)分组中,真实值true和预测值pred均为'P'的样本数(真正例),原始代码如下:
import pandas as pd import numpy as np import random repeating_times = 4 df = pd.DataFrame({"col1": [1, 2, 3, 4, 5]*repeating_times, "col2": ['a', 'b', 'c', 'd', 'e']*repeating_times, "true": ['P', 'P', 'N', 'P', 'N']*repeating_times, "pred": random.choices(["P", "N"], k=5*repeating_times)}) grps = df.groupby(by=["col1", "col2"]) true_pos = grps.apply(lambda gr: np.sum(gr[gr['pred'] == 'P']["true"] == 'P')) true_pos
这种方法的问题在于:apply(lambda)会对每个分组执行Python层面的循环和条件筛选,当数据量较大时,速度会显著下降。
高效优化方案:向量化+groupby.agg
通过向量化操作预先标记真正例,再结合groupby.agg进行聚合,能大幅提升性能。核心思路是利用Pandas/NumPy的C级向量化运算,避免Python层面的逐组循环:
import pandas as pd import numpy as np import random repeating_times = 4 df = pd.DataFrame({"col1": [1, 2, 3, 4, 5]*repeating_times, "col2": ['a', 'b', 'c', 'd', 'e']*repeating_times, "true": ['P', 'P', 'N', 'P', 'N']*repeating_times, "pred": random.choices(["P", "N"], k=5*repeating_times)}) # 向量化生成真正例标记列:true和pred均为'P'则为True,否则为False df["true_pos"] = (df["true"] == "P") & (df["pred"] == "P") # 分组聚合求和:布尔值会被自动转为1/0,求和即为真正例数量 true_pos = df.groupby(["col1", "col2"]).agg({"true_pos": "sum"}) true_pos
为什么这个方法更快?
- 向量化操作:
(df["true"] == "P") & (df["pred"] == "P")是基于NumPy的向量化运算,直接在C层面处理整个列,比逐组的Python条件筛选快几个数量级。 agg的高效性:groupby.agg使用Pandas内置的聚合函数(这里是sum),不需要额外的Python函数调用开销,比apply更适合这类简单的聚合需求。
内容的提问来源于stack exchange,提问作者Esi
相关产品推荐
相关产品推荐

