Python Pandas:使用唯一值连接行

时间:2014-11-27 15:23:01

标签: 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','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

它包含十几个具有重复值(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'。

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

我认为你可以这样做:

>>> 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

答案 1 :(得分:0)

您可以使用df.pivot_table(),尽管它似乎比df.groupby()慢一点(如罗曼的回答所建议):

>>> %timeit df.pivot_table(index=['a','b','c'], values=['c','d','e'], aggfunc=lambda x: ','.join(x)).reset_index()
6.17 ms ± 131 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

vs

>>> %timeit df.groupby(['a', 'b', 'c']).agg(lambda col: ','.join(col)).reset_index()
4.09 ms ± 95.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

此外,如果希望新列包含ACTUAL列表(而不是逗号分隔的list-as-string),则可以将lambda函数','.join(x)替换为list(x)。 而且,如果您希望列表仅包含唯一元素,则可以将lambda函数更改为list(set(x))