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

为何df.groupby(...).agg(set)与lambda x:set(x)执行结果不同?

关于Pandas中groupby.agg(set)与groupby.agg(lambda x: set(x))的差异问题

我之前也踩过这个坑,咱们结合你给出的测试数据把这个问题拆解明白:

首先先定义测试用的DataFrame:

import pandas as pd

df = pd.DataFrame({
    'user_id': [1, 2, 3, 4, 1, 2, 3],
    'class_type': ['Krav Maga', 'Yoga', 'Ju-jitsu', 'Krav Maga', 'Ju-jitsu','Krav Maga', 'Karate'],
    'instructor': ['Bob', 'Alice','Bob', 'Alice','Alice', 'Alice','Bob']
})

两种调用方式的结果差异

先看你给出的lambda包装的调用结果,这是完全符合预期的——每个用户对应的课程类型和教练都被转换成了无重复的集合:

df.groupby('user_id').agg(lambda x: set(x))

输出:

class_type       instructor
user_id
1         {Krav Maga, Ju-jitsu}  {Alice, Bob}
2         {Yoga, Krav Maga}     {Alice}
3         {Ju-jitsu, Karate}    {Bob}
4         {Krav Maga}           {Alice}

但如果直接使用df.groupby('user_id').agg(set),你会发现结果大概率和预期不符——比如在部分Pandas版本中,它可能返回包含Series索引的集合,或者触发奇怪的内部逻辑,导致结果不是单纯的列值集合。

背后的原因

核心问题出在Pandas对agg()参数的解析逻辑:

  • 当你用lambda x: set(x)时,相当于明确告诉Pandas:对每个分组后的单列Series对象x,直接把它的迭代值(也就是列里的实际数据)转换成集合。这个逻辑直白无歧义,完全按照你的预期执行。
  • 而直接传入set时,Pandas内部会尝试将其匹配为官方支持的内置聚合函数(比如sum、mean这类),但set并不是Pandas认可的聚合函数,所以在不同版本的Pandas中,它的处理路径会出现差异——有的版本会把整个Series对象传入set(导致集合里包含索引元素),有的版本甚至会直接抛出错误。

解决方案

如果想稳定地得到分组列值的集合,优先使用lambda包装的方式,也就是lambda x: set(x),它的行为更明确,不会受Pandas版本或内部逻辑变化的影响。如果追求更高性能,也可以用x.unique()再转集合,但lambda的方式可读性更好,更适合大多数场景。

内容的提问来源于stack exchange,提问作者MaxU - stand with Ukraine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:36:52