2016-11-07 131 views
2

有沒有辦法強制pandas.groupby返回一個DataFrame?下面是說明我的問題的例子:Pandas Groupby壞行

玩具數據框:

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 

任何人知道如何得到這個工作?

回答

2

您可以通過a列的unique值使用unstackreindex,因爲groupbya列:

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 

如果與最終df列名添加indexSeriespd.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