2017-03-06 88 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