给出以下数据框:
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(),结果如预期的那样,每组中的所有单元格都包含该组的总和。
这是一个错误还是我遗漏了什么?
答案 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