我有一个如下所示的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]
会启动我,但我不确定从那里开始。
这样做的好方法是什么?
答案 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,否则最终会得到索引对象。