【发布时间】:2019-03-04 13:09:49
【问题描述】:
我很好奇pandas groupby-apply 在apply 函数返回一个系列时的行为。
当序列长度不同时,它返回一个多索引序列。
In [1]: import pandas as pd
In [2]: df1=pd.DataFrame({'state':list("AABBB"),
...: 'city':list("vwxyz")})
In [3]: df1
Out[3]:
city state
0 v A
1 w A
2 x B
3 y B
4 z B
In [4]: def f(x):
...: return pd.Series(x['city'].values,index=range(len(x)))
...:
In [5]: df1.groupby('state').apply(f)
Out[5]:
state
A 0 v
1 w
B 0 x
1 y
2 z
dtype: object
这会返回一个Series 对象。
但是,如果每个系列都具有相同的长度,那么它会将其转为 DataFrame。
In [6]: df2=pd.DataFrame({'state':list("AAABBB"),
...: 'city':list("uvwxyz")})
In [7]: df2
Out[7]:
city state
0 u A
1 v A
2 w A
3 x B
4 y B
5 z B
In [8]: df2.groupby('state').apply(f)
Out[8]:
0 1 2
state
A u v w
B x y z
这真的是预期的行为吗?如果我们以这种方式使用 apply,我们是否要检查返回类型?或者apply 中是否有我不欣赏的选项?
如果您好奇,在我的实际用例中,返回的 Series 的长度将与组的长度相同。这似乎是transform 的理想案例,除了我发现apply 返回一个系列实际上在大型数据集上要快一个数量级。这可以是另一个话题。
编辑:根据 Parfait 的回答,我们当然可以这样做:
X=df.groupby('state').apply(f)
if not isinstance(X,pd.Series):
X=X.stack()
X
这将为df=df1 或df=df2 提供相同的输出类型。我想我只是在问这是否真的是正常或首选的处理方式。
【问题讨论】: