【问题标题】:join two pandas dataframes by two columns without order通过两列无顺序连接两个熊猫数据框
【发布时间】:2022-01-02 14:20:59
【问题描述】:

我有两个如下所示的数据框:

网络1

Gene_A Gene_B abs_dif log2FC omic
0 RBL2 ATOH7 0.277574 0.634319 trans
1 RBL2 USF2 0.276369 0.567421 trans
2 RBL2 RASA3 0.166101 0.474418 trans

网络2

Gene_A Gene_B abs_dif log2FC omic
0 ATOH7 RBL2 0.277574 0.634319 meth
1 RBL2 USF2 0.276369 0.567421 meth
2 RBL2 Fernando 0.166101 0.474418 meth

每一行代表一种关系。我正在尝试基于“Gene_A”和“Gene_B”列合并两个熊猫数据框,同时保持常见和不常见的关系。我正在使用:

merged = pd.merge(net1, net2, how='outer', on=["Gene_A", "Gene_B"], indicator=True)

返回:

Gene_A Gene_B abs_dif_x log2FC_x omic_x abs_dif_y log2FC_y omic_y _merge
0 RBL2 ATOH7 0.277574 0.634319 trans nan nan nan left_only
1 RBL2 USF2 0.276369 0.567421 trans 0.276369 0.567421 meth both
2 ATOH7 RBL2 nan nan nan 0.277574 0.634319 meth right_only
3 RBL2 Fernando nan nan nan 0.166101 0.474418 meth right_only

但是,两个表中0的关系基本相同,所以在合并时不应该考虑Gene_A和Gene_B的顺序。因此,合并数据框中的第一行应该是:

Gene_A Gene_B abs_dif_x log2FC_x omic_x abs_dif_y log2FC_y omic_y _merge
0 RBL2 ATOH7 0.277574 0.634319 trans 0.277574 0.634319 meth both

如何在不考虑合并数据框的两列中元素的顺序的情况下合并数据框?

【问题讨论】:

  • 接受并支持您认为有助于保持社区积极性的解决方案

标签: python pandas merge multiple-columns


【解决方案1】:

有很多方法可以做到这一点,我发现其中一种方法可能有效但有效:

对于数据框 1

net1['combined']=net1.apply(lambda x: str(set([x['Gene_A'], x['Gene_B']])),axis=1)

输出:

  Gene_A    Gene_B   abs_dif    log2FC  omic              combined
0  ATOH7      RBL2  0.277574  0.634319  meth     {'ATOH7', 'RBL2'}
1   RBL2      USF2  0.276369  0.567421  meth      {'RBL2', 'USF2'}
2   RBL2  Fernando  0.166101  0.474418  meth  {'Fernando', 'RBL2'}

对于dataframe2

net2['combined']=net2.apply(lambda x: str(set([x['Gene_A'], x['Gene_B']])),axis=1)

输出:

  Gene_A Gene_B   abs_dif    log2FC   omic           combined
0   RBL2  ATOH7  0.277574  0.634319  trans  {'ATOH7', 'RBL2'}
1   RBL2   USF2  0.276369  0.567421  trans   {'RBL2', 'USF2'}
2   RBL2  RASA3  0.166101  0.474418  trans  {'RBL2', 'RASA3'}

用于合并:

merged = pd.merge(net1, net2, how='outer', on=["combined"], indicator=True)

输出:

  Gene_A_x  Gene_B_x  abs_dif_x  log2FC_x omic_x              combined Gene_A_y Gene_B_y  abs_dif_y  log2FC_y omic_y      _merge
0    ATOH7      RBL2   0.277574  0.634319   meth     {'ATOH7', 'RBL2'}     RBL2    ATOH7   0.277574  0.634319  trans        both
1     RBL2      USF2   0.276369  0.567421   meth      {'RBL2', 'USF2'}     RBL2     USF2   0.276369  0.567421  trans        both
2     RBL2  Fernando   0.166101  0.474418   meth  {'Fernando', 'RBL2'}      NaN      NaN        NaN       NaN    NaN   left_only
3      NaN       NaN        NaN       NaN    NaN     {'RBL2', 'RASA3'}     RBL2    RASA3   0.166101  0.474418  trans  right_only

合并的数据框与预期一致,可以使用 drop 函数删除不必要的列。

【讨论】:

  • 谢谢!似乎工作正常!剩下的就是删除和完善输出
  • 很高兴它有帮助:)
【解决方案2】:

您可以在要用作无序键的列上使用apply 和frozenset。然后使用它们作为合并的关键:

key1 = net1[['Gene_A', 'Gene_B']].apply(frozenset, axis=1)
key2 = net2[['Gene_A', 'Gene_B']].apply(frozenset, axis=1)
net1.merge(net2, left_on=key1, right_on=key2)

输出:

           key_0 Gene_A_x Gene_B_x  abs_dif_x  log2FC_x omic_x Gene_A_y Gene_B_y  abs_dif_y  log2FC_y omic_y
0  (ATOH7, RBL2)     RBL2    ATOH7   0.277574  0.634319  trans    ATOH7     RBL2   0.277574  0.634319   meth
1   (USF2, RBL2)     RBL2     USF2   0.276369  0.567421  trans     RBL2     USF2   0.276369  0.567421   meth

注意。由于您有相同的列名,您可能需要执行一些清理操作。

【讨论】:

  • 使用frozenset 是有创意的,我使用字符串而不是因为set 不可散列。
  • @navaneeth 是的,frozensets 是可散列的。也可以使用排序的元组;)
  • 除了其他用户cmets,输出的不是对应的full join
  • @Fernando 为了清晰起见,我提供了最小的方法,添加您想要的任何参数 (how='outer', indicator=True) 进行合并很简单;)
猜你喜欢
  • 2016-03-22
  • 2019-12-28
  • 2020-10-13
  • 2015-08-15
  • 1970-01-01
  • 2021-11-19
  • 2022-10-06
  • 2016-03-13
  • 2021-05-11
相关资源
最近更新 更多