回答this question,结果df.groupby(...).agg(set)
和df.groupby(...).agg(lambda x: set(x))
产生了不同的结果。
数据:
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']})
演示:
In [36]: df.groupby('user_id').agg(lambda x: set(x))
Out[36]:
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}
In [37]: df.groupby('user_id').agg(set)
Out[37]:
class_type instructor
user_id
1 {user_id, class_type, instructor} {user_id, class_type, instructor}
2 {user_id, class_type, instructor} {user_id, class_type, instructor}
3 {user_id, class_type, instructor} {user_id, class_type, instructor}
4 {user_id, class_type, instructor} {user_id, class_type, instructor}
我希望这里有同样的行为 - 你知道我错过了什么吗?
答案 0 :(得分:10)
好了这里发生的事情is_list_like
没有被处理,因为_aggregate
中没有elif is_list_like(arg) and arg not in compat.string_types:
:
is_list_like
请参阅source
这不是None
所以它会在调用链上返回results.append(colg.aggregate(a))
以结束此行:
TypeError
请参阅source
这会将TypeError: 'type' object is not iterable
提升为if not len(results):
raise ValueError("no results")
然后提出:
_aggregate_generic
请参阅source
因为我们没有结果,我们最终会调用result[name] = self._try_cast(func(data, *args, **kwargs)
:
请参阅source
然后调用:
(Pdb) n
> c:\programdata\anaconda3\lib\site-packages\pandas\core\groupby.py(3779)_aggregate_generic()
-> return self._wrap_generic_output(result, obj)
(Pdb) result
{1: {'user_id', 'instructor', 'class_type'}, 2: {'user_id', 'instructor', 'class_type'}, 3: {'user_id', 'instructor', 'class_type'}, 4: {'user_id', 'instructor', 'class_type'}}
请参阅source
然后结束为:
set
我正在运行略有不同版本的pandas,但等效的源代码行是https://github.com/pandas-dev/pandas/blob/v0.22.0/pandas/core/groupby.py#L3779
所以基本上因为In [8]:
df.groupby('user_id').agg(lambda x: print(set(x.columns)))
{'class_type', 'instructor', 'user_id'}
{'class_type', 'instructor', 'user_id'}
{'class_type', 'instructor', 'user_id'}
{'class_type', 'instructor', 'user_id'}
Out[8]:
class_type instructor
user_id
1 None None
2 None None
3 None None
4 None None
不算作函数或者是可迭代的,它只是在系列迭代上调用ctor,在这种情况下是列,你可以在这里看到相同的效果:
lambda
但是当你使用{{1}}这是一个匿名函数时,它按预期工作。
答案 1 :(得分:2)
也许@Edchum评论agg
应用python内置函数,将groupby对象视为迷你数据帧,而当传递已定义的函数时,它会将其应用于每一列。举例说明这是通过印刷。
df.groupby('user_id').agg(print,end='\n\n')
class_type instructor user_id
0 Krav Maga Bob 1
4 Ju-jitsu Alice 1
class_type instructor user_id
1 Yoga Alice 2
5 Krav Maga Alice 2
class_type instructor user_id
2 Ju-jitsu Bob 3
6 Karate Bob 3
df.groupby('user_id').agg(lambda x : print(x,end='\n\n'))
0 Krav Maga
4 Ju-jitsu
Name: class_type, dtype: object
1 Yoga
5 Krav Maga
Name: class_type, dtype: object
2 Ju-jitsu
6 Karate
Name: class_type, dtype: object
3 Krav Maga
Name: class_type, dtype: object
...
希望这就是为什么应用set给出的结果如上所述。