df_a
和df_b
是两个数据帧,如下所示。它们的长度不同。
--> df_a
col_1 col_2
a b
c
d
e
f g
--> df_b
col_3
a
c
d
e
我知道我可以用实现AND子句的合并
df_a = pd.Dataframe({"col_1": ["a", "c", "d", None, "f"], "col_2": ["b", None, None, "e", "g"]})
df_b = pd.Dataframe({"col_3": ["a", "c", "d", "e"]})
pd.merge(df_a, df_b, how="inner", left_on=["col_1", "col_2"], right_on=["col_3", "col_3"])
我的需要是基于像col_1 == col_3 OR col_2 == col_3
这样的OR子句来合并它们。理想情况下,我不想单独进行两次合并。
感谢您的建议。
使用左双merge
,首先使用'col_1',然后使用'col_2'和combine_first
两个输出:
(df_a
.merge(df_b, left_on='col_1', right_on='col_3', how='left')
.combine_first(df_a.merge(df_b, left_on='col_2', right_on='col_3', how='left'))
)
输出:
col_1 col_2 col_3 col_4
0 a b a 0.0
1 c None c 1.0
2 d None d 2.0
3 None e e 3.0
4 f g NaN NaN
使用的输入(带额外的列(:
df_a = pd.DataFrame({"col_1": ["a", "c", "d", None, "f"],
"col_2": ["b", None, None, "e", "g"]})
df_b = pd.DataFrame({"col_3": ["a", "c", "d", "e"], "col_4": range(4)})
任意列数
您可以使用functools.reduce
和按首选匹配顺序排列的列列表(修改输入以查看差异,此处"col_2"的优先级高于"col_1"(:
cols = ['col_2', 'col_1']
from functools import reduce
out = reduce(lambda a,b: a.combine_first(b),
[df_a.merge(df_b, left_on=c, right_on='col_3', how='left')
for c in cols])
输出:
col_1 col_2 col_3 col_4
0 a c c 1.0
1 c None c 1.0
2 d None d 2.0
3 None e e 3.0
4 f g NaN NaN
修改输入:
df_a = pd.DataFrame({"col_1": ["a", "c", "d", None, "f"],
"col_2": ["c", None, None, "e", "g"]})
df_b = pd.DataFrame({"col_3": ["a", "c", "d", "e"], "col_4": range(4)})