使用x.unique()

时间:2015-10-23 04:49:33

标签: python pandas group-by dataframe

给出以下数据框:

tdf1 = pd.DataFrame({'A' : ['r1', 'r1', 'r1', 'r2', 'r2', 'r2', 'r3'],
                   'B' :  ['t1', 't1', 't2', 't3', 't4', 't4', 't5']})
>>> tdf1
    A   B
0  r1  t1
1  r1  t1
2  r1  t2
3  r2  t3
4  r2  t4
5  r2  t4
6  r3  t5

我想按列A对数据进行分组,并创建一个包含每个组中所有元素的列C.因此,生成的数据框应如下所示:

>>> res
   A   B   C
0  r1  t1  t1t2
1  r1  t1  t1t2
2  r1  t2  t1t2
3  r2  t3  t3t4
4  r2  t4  t3t4
5  r2  t4  t3t4
6  r3  t5  t5

我希望以下内容可以完成大部分工作:

tdf1.groupby('A')['B'].transform(lambda x:  x.unique())

但是不是为每个组获取一组唯一值,而是重复列B.看起来x.unique()应用于每个单元格而不是组中的所有单元格。

但是,如果列B有数字而不是使用x.unique(),我使用x.sum(),结果如预期的那样,每组中的所有单元格都包含该组的总和。

这是一个错误还是我遗漏了什么?

1 个答案:

答案 0 :(得分:1)

我不认为这是一个错误,transform将它获得的结果转换为相同的组大小,因此当您向它发送一个唯一元素列表时,它会重复列表,使其成为组的大小相同,因此对于第一组,您得到['t1','t2','t1'],然后在每个索引处应用每个元素。

如果您想要一个类似't1t2'的字符串,请在结果列中使用str.join加入结果并将其提供给transform。示例 -

tdf1['C'] = tdf1.groupby('A')['B'].transform(lambda x: ''.join(x.unique()))

演示 -

In [9]: tdf1
Out[9]:
    A   B
0  r1  t1
1  r1  t1
2  r1  t2
3  r2  t3
4  r2  t4
5  r2  t4
6  r3  t5

In [10]: tdf1.groupby('A')['B'].transform(lambda x: ''.join(x.unique()))
Out[10]:
0    t1t2
1    t1t2
2    t1t2
3    t3t4
4    t3t4
5    t3t4
6      t5
Name: B, dtype: object

如果您希望元素列'C'是该组的唯一元素列表,则需要在另一个列表中传递x.unique()。示例 -

tdf1['C'] = tdf1.groupby('A')['B'].transform(lambda x: [x.unique()])

演示 -

In [11]: tdf1.groupby('A')['B'].transform(lambda x: [x.unique()])
Out[11]:
0    [t1, t2]
1    [t1, t2]
2    [t1, t2]
3    [t3, t4]
4    [t3, t4]
5    [t3, t4]
6        [t5]
Name: B, dtype: object