根据列 A 或 B 合并数据帧

merge dataframes based on column A OR B

我需要合并两个数据框,但可以在右侧数据框的任意两列上进行合并。

df_1 = pd.DataFrame({'col' : ['a', 'b', 'c']})
df_2 = pd.DataFrame({'col_a' : ['a', 'b', np.nan], 'col_b' : ['z', np.nan, 'c']})
df_1.merge(df_2, how = 'left', left_on = 'col', right_on = 'col_a')

在上面的示例中,合并正在查找 col == 'a'col == 'b' 的匹配项,因为 df_2 在其 col_a 列中包含这些值。但我也希望它能找到与 df_2col_b == 'c' 的匹配项。如果正则表达式与合并一起工作,一个好的解决方案应该是这样的:

df_1.merge(df_2, how = 'left', left_on = 'col', right_on = 'col_a|col_b')

输出应如下所示:

col col_a   col_b
a    a      z
b    b      NaN
c    NaN    c

有什么想法吗?

您可以执行两个合并并使用 combine_first 来融合两个合并:

(df_1.merge(df_2, left_on='col', right_on='col_a', how='left')
     .combine_first(df_1.merge(df_2, left_on='col', right_on='col_b', how='left'))
)

输出:

  col col_a col_b
0   a     a     z
1   b     b   NaN
2   c   NaN     c

其他示例(没有已经对齐索引的陷阱):

df_1 = pd.DataFrame({'col' : ['a', 'c', 'b']})
df_2 = pd.DataFrame({'col_a' : ['b', np.nan, 'a'], 'col_b' : [np.nan, 'c', 'z']})

输出:

  col col_a col_b
0   a     a     z
1   c   NaN     c
2   b     b   NaN

根据您的输出,以免尝试加入

 df_1.join(df_2)

输出

col col_a   col_b
0   a   a   z
1   b   b   NaN
2   c   NaN c

或者

df_1.merge(df_2, how='left', left_on='col', right_on='col_a').combine_first(df_2)

输出

col col_a col_b
0   a     a     z
1   b     b   NaN
2   c   NaN     c

我相信我们在这里寻找的是合并两次,连接结果并删除可能因 col_acol_b 相同而导致的任何重复项。

import numpy as np
import pandas as pd

df_1 = pd.DataFrame({'col' : ['a', 'c', 'b']})
df_2 = pd.DataFrame({'col_a' : ['b', np.nan, 'a', 'a', 'c'], 'col_b' : [np.nan, 'c', 'z', 'b', 'c']})

df = (
    pd.concat([
        df_1.merge(df_2, left_on='col', right_on='col_a'),
        df_1.merge(df_2, left_on='col', right_on='col_b'),
    ]).drop_duplicates()
    .reset_index(drop=True)
)

print(df)
#   col col_a col_b
# 0   a     a     z
# 1   a     a     b
# 2   c     c     c
# 3   b     b   NaN
# 4   c   NaN     c
# 5   b     a     b

我们看到我们处理:

  1. a 匹配 col_a 两次
  2. b 分别匹配 col_acol_b(包括匹配 a 的行)
  3. c 同时匹配 col_acol_b 但在输出中不重复。