有没有办法强制pandas.groupby返回一个DataFrame?这是一个说明我问题的例子:
玩具数据框:
df = pd.DataFrame(data=dict(a=[1, 1, 1, 2, 2, 2, 3, 3, 3],
b=[1, 1, 1, 2, 2, 2, 4, 4, 4])
此函数按预期返回数据帧:
def fcn_good(d):
return pd.Series(data=dict(mean=d.b.mean(), std=d.b.std()))
print(df.groupby('a').apply(fcn_good))
带输出
mean std
a
1 1.0 0.0
2 2.0 0.0
3 4.0 0.0
现在问题就在于此。在我的实际代码中,某些groupby键在计算过程中会失败。我想要的输出是:
mean std
a
1 1.0 0.0
2 NaN NaN
3 4.0 0.0
然而,这段代码
def fcn_bad(d):
if int(d.a.unique()[0]) == 2: # Simulate failure
return pd.Series()
return pd.Series(data=dict(mean=d.b.mean(), std=d.b.std()))
print(df.groupby('a').apply(fcn_bad))
返回一个系列:
a
1 mean 1.0
std 0.0
3 mean 4.0
std 0.0
dtype: float64
任何人都知道如何让它发挥作用?
答案 0 :(得分:2)
您可以使用列a
的{{3}}值unstack
和reindex
,因为unique
位于列a
:
def fcn_bad(d):
if int(d.a.unique()[0]) == 2: # Simulate failure
return pd.Series()
return pd.Series(data=dict(mean=d.b.mean(), std=d.b.std()))
print(df.groupby('a').apply(fcn_bad).unstack().reindex(df.a.unique()))
mean std
a
1 1.0 0.0
2 NaN NaN
3 4.0 0.0
如果将index
的最终df
列添加到Series
pd.Series(index=['mean','std'])
,则会返回DataFrame
:
def fcn_bad(d):
if int(d.a.unique()[0]) == 2: # Simulate failure
return pd.Series(index=['mean','std'])
return pd.Series(data=dict(mean=d.b.mean(), std=d.b.std()))
print(df.groupby('a').apply(fcn_bad))
mean std
a
1 1.0 0.0
2 NaN NaN
3 4.0 0.0