首页 > 解决方案 > 为什么在使用 DataFrameGroupBy.agg 时可以访问传递给聚合函数的系列中的所有数据框列?

问题描述

我在玩弄我无法解释的对象的方法applyagg方法时进行了观察。DataFrameGroupBy


介绍

我理解以下代码,但它可能对问题的介绍很有用。

我正在分组DataFrame my_df

   key col0 col1
0    1    A    B
1    1    C    D
2    2    E    F
3    2    G    H

'key'列,然后apply按功能

def func(df): 
     return ''.join(df['col0'] + df['col1'])

产生

>>> my_df.groupby('key').apply(func)
key
1    ABCD
2    EFGH
dtype: object

这按预期工作。我可以访问这些列'col0',因为使用时'col1'传递的“分组块”是数据帧。funcapply


问题

我不明白为什么在使用而不是使用相同的功能KeyError时会引发no 。aggapply

>>> my_df.groupby('key').agg(func)                                     
     col0  col1
key            
1    ABCD  ABCD
2    EFGH  EFGH

据我了解,当使用aggthen时,为 的每一列的每个组func传递一个,所以参数应该是 type ,并且试图做并且应该产生一个.Series my_dfdfSeriesdf['col0']df['col1']KeyError

为什么会agg产生结果?我的在哪里KeyError


研究

我确认这df是一个Series不能用调试器df['col0']df['col1']调试器索引的。

然而my_df.groupby('key').agg(func)神奇地起作用。

设置:

from IPython.core.debugger import Pdb
import sys

def set_trace():
    Pdb().set_trace(sys._getframe().f_back)

def func(df): 
    set_trace() 
    return ''.join(df['col0'] + df['col1'])

用法:

>>> my_df.groupby('key').agg(func)
> <ipython-input-258-9f34bde72bce>(9)func()
      6 
      7 def func(df):
      8      set_trace()
----> 9      return ''.join(df['col0'] + df['col1'])
     10 

ipdb> type(df)
<class 'pandas.core.series.Series'>
ipdb> df
0    A
1    C
Name: col0, dtype: object
ipdb> df['col0']
*** KeyError: 'col0'
ipdb> df['col1']
*** KeyError: 'col1'

标签: pythonpandas

解决方案


它实际上确实引发了 a KeyError,您可以在将访问包装在时看到try/except

In [23]: def func(df): 
    ...:     print(type(df))
    ...:     print(df)
    ...:     print()
    ...:     try:
    ...:         df['col0']
    ...:     except KeyError:
    ...:         print('[Error]')
    ...:     return ''.join(df['col0'] + df['col1'])
    ...: 
    ...:
In [24]: df.groupby('key').agg(func)
<class 'pandas.core.series.Series'>
0    A
1    C
Name: col0, dtype: object
[Error]

<class 'pandas.core.series.Series'>
0    A
1    C
Name: col0, dtype: object
[Error]

<class 'pandas.core.series.Series'>
0    A
1    C
Name: 1, dtype: object
[Error]

<class 'pandas.core.frame.DataFrame'>
   key col0 col1
0    1    A    B
1    1    C    D

<class 'pandas.core.frame.DataFrame'>
   key col0 col1
2    2    E    F
3    2    G    H

KeyError似乎被调用函数排除在外,因此它被静音了。

检查一些源代码表明agg实际上调用了这个函数。从这里它首先进入这个函数,它返回Noneifarg是一个函数(这是我们的例子)。最后它会在这里try / except Exception执行。


推荐阅读