2017-03-06 142 views
0

我需要在df上運行自定義函數,並且希望能夠以與原始數據框完全相同的順序返回值的向量(例如,合併回原來的df,然後只使用新列)。Python熊貓 - 將groupby結果合併到原始數據框中

目前我的函數返回一個簡單的列表,這會導致與索引列和另一列其中包括列表中的系列,見下文

我如何可以結合該結果回DF?

其他一些信息: 1.我的功能包括一些業務邏輯和需要訪問該組中的所有colls,所以我不能使用transofrm 2.我試圖用系列作爲返回類型,但隨後得到了類型錯誤SERIS。名稱必須是哈希的(即使我設置返回之前的系列名稱) 3.我想避免使用數據幀作爲函數的結果

import pandas as pd 
import random 

df=pd.DataFrame({"x":[1,1,2,1,2,2,1,3,1,2,3,2],"y":[random.random() for _ in range(12)]}) 

def myfun(rs,rownum=0): 
    if rownum >= len(rs): return [] 
    return [rs.y] + myfun(rs,rownum+1) 

q=df.groupby(df.x).apply(myfun) 

結果:

x 
1 [[0.199527553305, 0.652730337948], [0.19952755... 
2 [[0.58150463154, 0.882898367661], [0.581504631... 
3 [[0.793173748785, 0.29465803134], [0.793173748... 

更新:下面的腳本做我想要的。我發現它的工作的唯一辦法是,如果我保存在原記錄的索引值,然後通過這個數字更新:

import pandas as pd 
import random 

df=pd.DataFrame({"x":[1,1,2,1,2,2,1,3,1,2,3,2],"y":[random.random() for _ in range(12)]}) 

def myfun(rs): 
    def myfun_loop(rs,rownum=0,idx=[],val=[]): 
     if rownum >= len(rs): 
      return (idx,val) 
     return myfun_loop(rs,rownum+1,idx+[rs.index[rownum]],val+[rownum]) 
    v=myfun_loop(rs) 
    return pd.DataFrame({"idx":v[0],"val":v[1]}) 


g=df.groupby(df.x) 
q=g.apply(lambda x:pd.DataFrame(myfun(x))) 
q.set_index(["idx"],inplace=True) 
df["val"]=None 
df.update(q) 
+0

你究竟想達到什麼目的?目前,你的函數返回一個相同的系列列表,而不是「一個簡單的列表」。當應用於GroupBy對象時,這會給出一系列Series(檢查'type(q)','type(q [1])','type(q [1] [0])')的輸出。所以你首先需要修復你的函數的輸出。 –

+0

我用一個工作示例更新了這篇文章,但實現相當難看。有沒有更好的辦法? – dkone

回答

0

下面的代碼做你做什麼,只是更簡潔:

df["val"] = df.groupby(df.x).apply(
       lambda rs: pd.DataFrame(
        {"idx": rs.index, 
        "val": rs.reset_index().index}) 
      ).set_index(["idx"]) 

這樣就不需要定義一個遞歸函數來實現這個功能。

+0

遞歸確實是在這裏,我從一個複雜的例子複製代碼。 所以,如果我理解正確,當一個人指派一個DF到另一個列時,索引用於下面加入他們?這是我錯過的重要細節! – dkone