2014-04-10 82 views
0

說我有以下的數據幀向下傳播GROUPBY聚合的結果

     X   Y 
A B  C      
bar one P 0.630667 1.457555 
    three Q 1.163132 -0.944378 
      T 0.423349 0.432508 
flux six P -1.055297 -0.419939 
    three T 2.064113 0.465885 
foo five Q 0.271349 0.472808 
      S -0.985560 -0.301500 
      P -0.482336 -0.089823 
      R 0.745047 -0.713639 

我需要的B針對X具有最高值的每個值的範圍內確定C水平的價值,並傳播回每一行。

結果應該是:

     X   Y W 
A B  C      
bar one P 0.630667 1.457555 P 
    three Q 1.163132 -0.944378 Q 
      T 0.423349 0.432508 Q 
flux six P -1.055297 -0.419939 P 
    three T 2.064113 0.465885 T 
foo five Q 0.271349 0.472808 R 
      S -0.985560 -0.301500 R 
      P -0.482336 -0.089823 R 
      R 0.745047 -0.713639 R 

我怎麼能這樣做?

到目前爲止,我有大意如下的內容:

df.groupby(level=['A', 'B']).agg(lambda x: x.max()) 

,但我不知道怎麼去「傳播」下來的結果,以原始行。

回答

2

如果我理解你,你可以結合transform(這是「向下傳播」的一部分,雖然我一直認爲它是廣播上)與idxmax

>>> df["W"] = df.groupby(level=["A", "B"])["X"].transform(lambda x: x.idxmax()[2]) 
>>> df 
        X   Y W 
A B  C      
bar one P 0.630667 1.457555 P 
    three Q 1.163132 -0.944378 Q 
      T 0.423349 0.432508 Q 
flux six P -1.055297 -0.419939 P 
    three T 2.064113 0.465885 T 
foo five Q 0.271349 0.472808 R 
      S -0.985560 -0.301500 R 
      P -0.482336 -0.089823 R 
      R 0.745047 -0.713639 R 

[9 rows x 3 columns] 
+0

感謝。我特別感興趣的解決方案適用於任何** lambda /函數,我使用聚合(對不起,最大的lambda只是爲了舉例)。這將適用於任何lambda? –

+0

謝謝。它確實有效。我無法相信它就像使用'transform'而不是'lambda'一樣簡單! –

1

想未使用transform一個?

In [101]: 

df2=pd.DataFrame(df.groupby(level=['A', 'B'])['X'].agg(np.argmax).apply(lambda x: x[-1])) 
#or pd.DataFrame(df.groupby(level=['A', 'B'])['X'].agg(lambda x: x.idxmax()[-1])) 
df['W']=df2.loc[df.index.droplevel(2)].values 
In [102]: 

print df 
        X   Y W 
A B  C      
bar one P 0.630667 1.457555 P 
    three Q 1.163132 -0.944378 Q 
      T 0.423349 0.432508 Q 
flux six P -1.055297 -0.419939 P 
    three T 2.064113 0.465885 T 
foo five P -0.482336 -0.089823 Q 
      Q 0.271349 0.472808 Q 
      R -0.745047 -0.713639 Q 
      S -0.985560 -0.301500 Q 

[9 rows x 3 columns] 

這是很容易得到這個角色, 在[115]:

print pd.DataFrame(df.groupby(level=['A', 'B'])['X'].agg(lambda x: x.idxmax()[-1])) 
      X 
A B  
bar one P 
    three Q 
flux six P 
    three T 
foo five Q 

[5 rows x 1 columns] 

,但它並不像兩岸轉發給其分配追溯到'W'