无序地按两列连接两个 pandas 数据帧

join two pandas dataframes by two columns without order

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

net1

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

net2

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' 合并两个 pandas 数据框,同时保持常见和不常见的关系。我正在使用:

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

哪个returns:

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

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

您可以在要用作无序键的列上 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

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

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

对于数据帧 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'}

对于数据框 2

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

合并数据框符合预期,可以使用删除功能删除不必要的列。