Pandas groupby,其中所有列都添加到以列名为前缀的列表中

时间:2016-09-18 21:35:22

标签: python pandas

我有一个如下所示的CSV文件:

D/TAG: onDestroy
D/TAG: listenerNotified

我将其读入带有id1,feat1,feat2,feat3 a,b,asd,asg c,d,dg,ag a,e,sdg,as c,f,as,sdg c,g,adg,sd 的数据框。

我希望按df = pd.read_csv("file.csv")进行分组,并将组中一行中的所有其他列与添加的标题名称组合为前缀。那就是输出应该是一个看起来像这样的数据框:

id1

a [feat1=b,feat1=e,feat2=asd,feat2=sdg,feat3=asg,feat3=as] c [feat1=d,feat1=f,feat1=g,feat2=dg,feat2=as,feat2=adg,feat3=ag,feat3=sdg,feat3=sd] 会启动我,但我不确定从那里开始。

这样做的好方法是什么?

2 个答案:

答案 0 :(得分:2)

您可以在apply对象上使用自定义函数groupby,函数调用apply再次传递给系列,将列名和值压缩成列表,然后我们再执行列表推导并根据需要将其返回到列表中:

In [54]:    
def foo(x):
    l = (x.apply(lambda x: x.name + '=' + x)).values.tolist()
    return pd.Series([[i for j in l for i in j]])
​
gp = df.groupby('id1')[['feat1','feat2','feat3']]
gp1 = gp.apply(foo)
gp1

Out[54]:
                                                     0
id1                                                   
a    [feat1=b, feat2=asd, feat3=asg, feat1=e, feat2...
c    [feat1=d, feat2=dg, feat3=ag, feat1=f, feat2=a...

如果我们查看内容,我们会看到我们有一个值列表:

In [55]:    
gp1.iloc[0].values

Out[55]:
array([['feat1=b', 'feat2=asd', 'feat3=asg', 'feat1=e', 'feat2=sdg', 'feat3=as']], dtype=object)

答案 1 :(得分:1)

应用此功能将起作用:

def func(dfg):
    dfu = dfg.unstack()
    result = dfu.index.get_level_values(0) + '=' + dfu.values
    return result.tolist()

df.groupby('id1').apply(func)

解释:让我们考虑一个组,例如dfg = df[df['id1'] == 'c']

dfg.unstack()
Out[35]: 
id1    1      c
       3      c
       4      c
feat1  1      d
       3      f
       4      g
feat2  1     dg
       3     as
       4    adg
feat3  1     ag
       3    sdg
       4     sd

通过取消堆栈,您可以获得与列名称对齐的值(忽略其间的索引值)。您需要做的只是连接:

dfu.index.get_level_values(0) + '=' + dfu.values
Out[36]: 
Index(['feat1=d', 'feat1=f', 'feat1=g', 'feat2=dg', 'feat2=as', 'feat2=adg',
       'feat3=ag', 'feat3=sdg', 'feat3=sd'],
      dtype='object')

最后,在返回之前转换为list,否则最终会得到索引对象。