使用以下数据框:
import pandas as pd
df=pd.DataFrame(data=[[1,5179530,'rs10799170',8.1548,'E001'], [1,5179530,'rs10799170',8.1548,'E002'], [1,5179530,'rs10799170',8.1548,'E003'], [1,455521,'rs235884',2.584,'E003'], [1,455521,'rs235884',2.584,'E007']], col umns=['CHR','BP','SNP','CM','ANNOT'])
CHR BP SNP CM ANNOT
0 1 5179530 rs10799170 8.1548 E001
1 1 5179530 rs10799170 8.1548 E002
2 1 5179530 rs10799170 8.1548 E003
3 1 455521 rs235884 2.5840 E003
4 1 455521 rs235884 2.5840 E007
我想获得
CHR BP SNP CM E001 E002 E003 E007
0 1 5179530 rs10799170 8.1548 1 1 1 0
1 1 455521 rs235884 2.5840 0 0 1 1
我分别尝试groupby()
和get_dummies()
df.groupby(['CHR','BP','SNP','CM']).sum()
CHR BP SNP CM ANNOT
1 455521 rs235884 2.5840 E003E007
5179530 rs10799170 8.1548 E001E002E003
pd.get_dummies(df['ANNOT'])
E001 E002 E003 E007
0 1 0 0 0
1 0 1 0 0
2 0 0 1 0
3 0 0 1 0
4 0 0 0 1
但我不知道如何将两者结合起来或者如果有另一种方式。
答案 0 :(得分:4)
正如@Dadep在评论中指出的那样,这可以通过数据透视表来实现。如果你想坚持get_dummies
+ groupby
技术,你可以做类似的事情:
pd.concat([df, pd.get_dummies(df.ANNOT)], 1).groupby(['CHR','BP','SNP','CM']).sum().reset_index()
首先连接您的数据框和get_dummies
调用的输出,然后根据相关列对结果进行分组,在这些组中获取这些列的总和,然后重置索引,这样您就不会#39 ; t必须处理多索引数据帧。结果如下:
CHR BP SNP CM E001 E002 E003 E007
0 1 455521 rs235884 2.5840 0 0 1 1
1 1 5179530 rs10799170 8.1548 1 1 1 0
答案 1 :(得分:4)
你非常接近!只需将两种技术结合起来:
dummies = pd.get_dummies(df['ANNOT'])
combine = pd.concat([df, dummies], axis=1)
out = combine.groupby(['BP','CHR','SNP','CM']).sum().reset_index()
或者,根据您的应用,您可能希望使用.max
代替sum
。请注意,我更改了groupby中的顺序以阻止一个CHR组。只需按照您想要的顺序获得结果:
out = out[['CHR', 'BP', 'SNP', 'CM'] + list(dummies)]
答案 2 :(得分:4)
这是一种方法,使用groupby
和apply
In [66]: (df.groupby(['CHR', 'BP', 'SNP', 'CM'])
.apply(lambda x: {y:1 for y in x['ANNOT']})
.apply(pd.Series)
.fillna(0)
.reset_index())
Out[66]:
CHR BP SNP CM E001 E002 E003 E007
0 1 455521 rs235884 2.5840 0.0 0.0 1.0 1.0
1 1 5179530 rs10799170 8.1548 1.0 1.0 1.0 0.0