2015-12-04 193 views
2

比方說,我有兩個簡單的數據幀:GROUPBY從另一列(同#行)數據幀

x1 = pd.DataFrame({'a':[1,2,3,4], 
        'b':[10,10,20,20], 
        'c':['z','z','z','o']}) 
x2 = pd.DataFrame({'e':['foo', 'bar', 'foo', 'foo'], 
        'f':['baz', 'blah', 'baz', 'blah']}) 
> x1 
    a b c 
0 1 10 z 
1 2 10 z 
2 3 20 z 
3 4 20 o 
> x2 
    e  f 
0 foo baz 
1 bar blah 
2 foo baz 
3 foo blah 

我想一個函數應用於基於列在x2x1組。

x1['avg'] = x1.groupby(x2[['e', 'f']])['a'].transform(np.mean) 
*** ValueError: Grouper for '<class 'pandas.core.frame.DataFrame'>' not 1-dimensional 

但我得到這個值的錯誤。

如果GROUPBY分從X1來(但我不希望有分配x2x1,代碼整潔原因,我不會進入,不會發生錯誤。

x1.groupby(['b', 'c'])['a'].transform(np.mean) 
0 1.5 
1 1.5 
2 3.0 
3 4.0 

這究竟是爲什麼/我能避開它?

回答

3

你不能傳遞一個數據幀,但你可以通過一個(列表)系列:

In [11]: x1.groupby([x2.e, x2.f])["a"].transform("mean") 
Out[11]: 
0 2 
1 2 
2 2 
3 4 
dtype: int64 

更普遍,你可以用一個列表理解這樣做(如果你通過所有列在另一個數據幀分組):

In [12]: x1.groupby([x2[col] for col in x2])["a"].transform("mean") 
Out[12]: 
0 2 
1 2 
2 2 
3 4 
dtype: int64 

這就是說,它可能是更好的前進,做加入... IMO它往往是一個好主意,讓你的變量獨立。

+0

有趣的,這不是@亞歷山大的解決方案在0.19.x下工作...也許是一個熊貓的錯誤​​,打破了這一點? – Kartik

+0

@Kartik在0.19.1中適合我! (亞歷山大沒有,但也許這是一個python 3的問題...我得到一個不可調用的zip,或者如果我把它作爲列表'GroupByError:len(index)!= len(labels)',如我之前所述) –

+0

是的,這是一個0.19.0的具體問題。我以爲我已經更新了我的env,但是不會。 [這是問題](http://stackoverflow.com/q/40986701/3765319)我問,然後投票結束。 – Kartik

3

您可以壓縮的兩列在一起,並通過成對的元組到您的groupby

>>> x1.groupby(zip(x2['e'], x2['f']))['a'].transform(np.mean) 
0 1 
1 2 
2 3 
3 4 
Name: a, dtype: int64 
+0

我*認爲*做zip會在這裏效率低下。 –

+0

可能。我相信你的解決方案更清潔,爲什麼我選擇了它。但我不明白爲什麼我們的結果不同。 – Alexander

+0

有趣!另外這個'x1.groupby(list(zip(x2 ['e'],x2 ['f'])))[「b」]。transform(「mean」)'給了我一個'GroupByError:len(index) != len(標籤)'這對我來說看起來不正確。肯定是一隻熊貓的bug ... –