Python:使用唯一值连接行

Python:使用唯一值连接行,python,pandas,Python,Pandas,在Python pandas中,我有一个大数据帧,如下所示: df = pd.DataFrame ({'a' : ['foo', 'bar'] * 3, 'b' : ['foo2', 'bar2'] * 3, 'c' : ['foo3', 'bar3'] * 3, 'd' : ['q','w','e','r','t','y'], 'e' : ['q2','w2','e2','r2','t2',

在Python pandas中,我有一个大数据帧,如下所示:

df = pd.DataFrame ({'a' : ['foo', 'bar'] * 3,
             'b' : ['foo2', 'bar2'] * 3,
             'c' : ['foo3', 'bar3'] * 3,
             'd' : ['q','w','e','r','t','y'],
             'e' : ['q2','w2','e2','r2','t2','y2']})


     a     b     c  d   e
1  bar  bar2  bar3  w  w2
3  bar  bar2  bar3  r  r2
5  bar  bar2  bar3  y  y2
4  foo  foo2  foo3  t  t2
2  foo  foo2  foo3  e  e2
0  foo  foo2  foo3  q  q2
>>> df.groupby(['a', 'b', 'c']).agg(lambda col: ','.join(col))
                   d         e
a   b    c                    
bar bar2 bar3  w,r,y  w2,r2,y2
foo foo2 foo3  q,e,t  q2,e2,t2
它包含十几个具有重复值(a、b、c…)的列,以及一些具有唯一值(d、e)的列。我想删除所有重复的值并收集唯一的值,即:

     a     b     c  d   e
1  bar  bar2  bar3  w,r,y  w2,r2,y2
4  foo  foo2  foo3  t,e,q  t2,e2,q2
我们可以安全地假设唯一值仅在“d”和“e”中,而其余值总是重复的

我可以设想的一种解决方案是按所有重复列分组,然后对唯一值应用串联操作:

df.groupby([df.a, df.b, df.c]).apply(lambda x: "{%s}" % ', '.join(x.d))
一个不便之处是,如果我想在输出中列出所有重复的列,就必须列出它们。更大的问题是,我只连接“d”中的字符串,同时还需要“e”


有什么建议吗?

我想你可以这样做:

df = pd.DataFrame ({'a' : ['foo', 'bar'] * 3,
             'b' : ['foo2', 'bar2'] * 3,
             'c' : ['foo3', 'bar3'] * 3,
             'd' : ['q','w','e','r','t','y'],
             'e' : ['q2','w2','e2','r2','t2','y2']})


     a     b     c  d   e
1  bar  bar2  bar3  w  w2
3  bar  bar2  bar3  r  r2
5  bar  bar2  bar3  y  y2
4  foo  foo2  foo3  t  t2
2  foo  foo2  foo3  e  e2
0  foo  foo2  foo3  q  q2
>>> df.groupby(['a', 'b', 'c']).agg(lambda col: ','.join(col))
                   d         e
a   b    c                    
bar bar2 bar3  w,r,y  w2,r2,y2
foo foo2 foo3  q,e,t  q2,e2,t2
另一种方法是不列出所有列,而只列出具有唯一值的列

>>> gr_columns = [x for x in df.columns if x not in ['d','e']]
>>> df.groupby(gr_columns).agg(lambda col: ','.join(col))
                   d         e
a   b    c                    
bar bar2 bar3  w,r,y  w2,r2,y2
foo foo2 foo3  q,e,t  q2,e2,t2

您可以使用
df.pivot\u table()
,尽管它似乎比
df.groupby()
稍慢(正如Roman的回答所建议的):

vs

此外,如果希望新列包含实际列表(而不是逗号分隔的字符串列表),可以替换lambda函数
,'。将(x)
连接为
list(x)

如果您希望列表只包含唯一的元素,您可以将lambda函数更改为
list(set(x))

只是暂时搁置,您不需要将列作为df列传递,以下内容就足够了:
df.groupby(['a','b','c'])。apply(lambda x:“{%s}”%,'。join(x.d))
谢谢!我使用df表示法的原因是,最初这些名称非常长,所以我利用了自动完成机制。为了不让其他人知道细节,我将它们替换为字母。请注意,
lambda col:','。join(col)
可以写成
,'。join
。。但仔细想想,我不确定这是否有效,因为我不确定OP希望对“独特”有多严格。(也就是说,如果是
'w,w,y'
的话,我们可能不得不去掉这两个
w
。)谢谢,效果很好!组中的所有值都是唯一的,因此“,”.join也可以工作。谢谢你的建议!罗曼的“正确答案”仍然有效,但现在我确实会使用这种方法。