numpy 无循环 Dataframe 之间的比较

axzmvihb  于 2023-04-06  发布在  其他
关注(0)|答案(2)|浏览(145)

我有两个 Dataframe 结构如下:
Df1:
| 基因ID|围棋术语|
| --------------|--------------|
| 识别码1|GO1|
| 识别码1|GO2|
| ID2|GO1|
| ID2|GO3|
| ID3|GO1|
| ID4|GO1|
Df2:
| MP术语|议员姓名|基因ID|
| --------------|--------------|--------------|
| MP1|姓名1|ID1、ID2、ID4|
| MP2|姓名2|ID1、ID3|
| MP3|姓名3|ID2|
现在,我想创建第三个 Dataframe ,以这种方式将前两个 Dataframe 组合在一起:
Df3:
| 基因ID|MP术语|GO术语|
| --------------|--------------|--------------|
| 识别码1|MP1、MP2|GO1、GO2|
| ID2|MP1、MP3|GO1、GO3|
| ID3|MP2|GO1|
| ID4|MP1|GO1|
第一列是Df 1的id(不重复),在第二列中,来自Df 2的mp与id相关联,在第三列中,来自Df 1的go项与基因id相关联。我可以用嵌套循环的for循环来实现,但我知道这是一种非常低效的方法。我想知道如何避免循环。非常感谢你的帮助。

u1ehiz5o

u1ehiz5o1#

您可以使用groupby.agg将具有公共ID的行连接为字符串,并使用split + explode扩展到多行。最后merge这两个部分来对齐您的输出:

out = (
 df1.groupby('gene ids', as_index=False).agg(','.join)
    .merge((df2.assign(**{'gene ids': lambda d: d['gene ids'].str.split(r',\s*')}).explode('gene ids')
               .groupby('gene ids', as_index=False).agg(', '.join)
            ), how='left')
)

输出:

gene ids Go terms  MP terms      MP names
0      ID1  GO1,GO2  MP1, MP2  Name1, Name2
1      ID2  GO1,GO3  MP1, MP3  Name1, Name3
2      ID3      GO1       MP2         Name2
3      ID4      GO1       MP1         Name1

如果您对“MP names”列不感兴趣,请在第二个groupby.agg中切片:

out = (
 df1.groupby('gene ids', as_index=False).agg(','.join)
    .merge((df2.assign(**{'gene ids': lambda d: d['gene ids'].str.split(r',\s*')}).explode('gene ids')
               .groupby('gene ids', as_index=False)['MP terms'].agg(', '.join)
            ), how='left')
)

输出:

gene ids Go terms  MP terms
0      ID1  GO1,GO2  MP1, MP2
1      ID2  GO1,GO3  MP1, MP3
2      ID3      GO1       MP2
3      ID4      GO1       MP1
ni65a41a

ni65a41a2#

使用concatGroupBy.agg的聚合以及joindf2,拆分的DataFrame.explode值:

df = pd.concat([df2.assign(**{'gene ids': df2['gene ids'].str.split(',\s*')})
                   .explode('gene ids')
                   .groupby('gene ids')['MP terms'].agg(', '.join),
                df1.groupby('gene ids')['Go terms'].agg(', '.join)], axis=1).reset_index()
print (df)
  gene ids  MP terms  Go terms
0      ID1  MP1, MP2  GO1, GO2
1      ID2  MP1, MP3  GO1, GO3
2      ID3       MP2       GO1
3      ID4       MP1       GO1

如果需要按join聚合所有列,请用途:

df = pd.concat([df2.assign(**{'gene ids': df2['gene ids'].str.split(',\s*')})
                   .explode('gene ids')
                   .groupby('gene ids').agg(', '.join),
                df1.groupby('gene ids').agg(', '.join)], axis=1).reset_index()
print (df)
  gene ids  MP terms      MP names  Go terms
0      ID1  MP1, MP2  Name1, Name2  GO1, GO2
1      ID2  MP1, MP3  Name1, Name3  GO1, GO3
2      ID3       MP2         Name2       GO1
3      ID4       MP1         Name1       GO1

相关问题