2017-08-16 57 views
2

假設我有兩個層次的多索引的數據幀如何在熊貓中聚合子數據框?

In [1]: index = pd.MultiIndex.from_tuples([(i,j) for i in range(3) 
     :           for j in range(1+i)], names=list('ij')) 
     : df = pd.DataFrame(0.1*np.arange(2*len(index)).reshape(-1,2), 
     :     columns=list('xy'), index=index) 
     : df 
Out[1]: 
     x y 
i j 
0 0 0.0 0.1 
1 0 0.2 0.3 
    1 0.4 0.5 
2 0 0.6 0.7 
    1 0.8 0.9 
    2 1.0 1.1 

而且我想在每個子數據幀運行自定義功能:

In [2]: def my_aggr_func(subdf): 
     :  return subdf['x'].mean()/subdf['y'].mean() 
     : 
     : level0 = df.index.levels[0].values 
     : pd.DataFrame({'mean_ratio': [my_aggr_func(df.loc[i]) for i in level0]}, 
     :    index=pd.Index(level0, name=index.names[0])) 
Out[2]: 
    mean_ratio 
i 
0 0.000000 
1 0.750000 
2 0.888889 

有一種優雅的方式與df.groupby('i').agg(__something__)做或類似的東西?

回答

2

極品GroupBy.apply,這與DataFrame工作:

df1 = df.groupby('i').apply(my_aggr_func).to_frame('mean_ratio') 
print (df1) 
    mean_ratio 
i    
0 0.000000 
1 0.750000 
2 0.888889 
+1

謝謝!我完全忘記了'申請'。 –

1

你不需要自定義函數。你可以用agg來計算「內部組的意思」,然後執行eval來獲得你想要的比例。

df.groupby('i').agg('mean').eval('x/y') 

i 
0 0.000000 
1 0.750000 
2 0.888889 
dtype: float64 
+0

我想要更復雜的東西。例如,擬合具有一些函數和輸出參數的'y(x)'。 –

+0

我建議你接受@ jezrael的答案,然後問你的具體問題。通常,SO上的某個人可以幫助爲更復雜的問題尋找更復雜的解決方案。如果「適合」意味着迴歸,你可能會考慮在你的新問題上加上一個「sklearn」和「numpy」標籤。那樣,遵循這些標籤而不是'熊貓'的其他聰明人也會看到它。 – piRSquared