df.groupby(...).agg(set)与df.groupby(...)相比产生不同的结果.agg(lambda x:set(x))

Max*_*axU 17 python pandas pandas-groupby

回答这个问题,事实证明,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']})
Run Code Online (Sandbox Code Playgroud)

演示:

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}
Run Code Online (Sandbox Code Playgroud)

我希望这里有同样的行为 - 你知道我错过了什么吗?

EdC*_*ica 11

OK这里发生了什么是set不被处理,因为它不是is_list_like_aggregate:

elif is_list_like(arg) and arg not in compat.string_types:
Run Code Online (Sandbox Code Playgroud)

来源

这不是is_list_like这样,它None会使调用链返回到此行:

results.append(colg.aggregate(a))
Run Code Online (Sandbox Code Playgroud)

来源

这引起了TypeErrorTypeError: 'type' object is not iterable

然后提出:

if not len(results):
    raise ValueError("no results")
Run Code Online (Sandbox Code Playgroud)

来源

因为我们没有结果,我们最终打电话_aggregate_generic:

来源

然后调用:

result[name] = self._try_cast(func(data, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

来源

然后最终结果如下:

(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'}}
Run Code Online (Sandbox Code Playgroud)

我正在运行一个稍微不同的熊猫版本,但等效的源代码行是https://github.com/pandas-dev/pandas/blob/v0.22.0/pandas/core/groupby.py#L3779

因此,基本上因为set不算作函数或迭代,它只是折叠到调用系列iterable上的ctor,在这种情况下是列,你可以在这里看到相同的效果:

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
Run Code Online (Sandbox Code Playgroud)

但是当你使用lambda哪个是匿名函数时,它按预期工作.

  • 很棒的工作.也许考虑用硬编码标签/提交替换指向`master`的前五个链接,因此它们在未来仍然有意义.我没有得到`is_aggregator`部分,这似乎只适用于`isinstance(arg,dict)`? (2认同)