2 回答

TA贡献1802条经验 获得超10个赞
它实际上确实引发了一个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进行。

TA贡献1858条经验 获得超8个赞
agg将整个 DataFrame 传递给func. 从文档中,
func : 函数、字符串、字典或字符串/函数列表 用于聚合数据的函数。如果是函数,则必须在传递 DataFrame 或传递给DataFrame.apply.
我相信这意味着该函数实际上是由 调度的apply,已知它对整个 DataFrame 进行操作。
你可以print在里面通过一个简单的调用来公开它func:
def func(df):
print(type(df))
return ''.join(df['col0'] + df['col1'])
df.groupby('key').agg(func)
<class 'pandas.core.series.Series'>
<class 'pandas.core.series.Series'>
<class 'pandas.core.series.Series'>
<class 'pandas.core.frame.DataFrame'>
<class 'pandas.core.frame.DataFrame'>
Out[87]:
col0 col1
key
1 ABCD ABCD
2 EFGH EFGH
所以它确实得到了两个 DataFrame 调用。但它也有 3 个带有 Series 参数的调用,我无法解释为什么会这样,也许是一个错误(我无法在任何地方看到它的记录)。
好吧,仔细想想,这是我能想到的最好的办法。现在,agg不确定您的函数想要如何处理数据,因此它将尝试两种方法并使用首先作为系列工作的任何输出。这似乎是一个实现细节,但 Series 是第一个用于传入数据的方法。如果这不起作用,则回退是传递一个 DataFrame 并希望它成功。让我看看我是否可以让它在一个例子中工作......
from itertools import count
c = count(0)
def func(x):
i = next(c)
print(i, type(x))
if i <3:
return 'xyz'
return ((df['col0'] + df['col1']).tolist())
df.groupby('key').agg(func)
0 <class 'pandas.core.series.Series'>
1 <class 'pandas.core.series.Series'>
2 <class 'pandas.core.series.Series'>
3 <class 'pandas.core.series.Series'>
Out[126]:
col0 col1
key
1 xyz xyz
2 xyz [AB, CD, EF, GH]
接下来,改变循环条件,我们有:
def func(x):
i = next(c)
print(i, type(x))
if i in {0, 1}:
return 'xyz'
return ((x['col0'] + x['col1']).tolist())
df.groupby('key').agg(func)
0 <class 'pandas.core.series.Series'>
1 <class 'pandas.core.series.Series'>
2 <class 'pandas.core.series.Series'>
3 <class 'pandas.core.series.Series'>
4 <class 'pandas.core.series.Series'>
5 <class 'pandas.core.frame.DataFrame'>
6 <class 'pandas.core.frame.DataFrame'>
Out[157]:
col0 col1
key
1 AB CD
2 EF GH
并且,更改i in {0, 1}为i in {0, 4},
0 <class 'pandas.core.series.Series'>
1 <class 'pandas.core.series.Series'>
2 <class 'pandas.core.series.Series'>
3 <class 'pandas.core.series.Series'>
4 <class 'pandas.core.frame.DataFrame'>
5 <class 'pandas.core.frame.DataFrame'>
Out[158]:
col0 col1
key
1 xyz xyz
2 EF GH
请注意函数类型的数量如何根据每次返回的内容而变化。
添加回答
举报