首页 > 解决方案 > 合并多个列上的两个数据框,但如果两者都不是 NaN,则仅在列上合并

问题描述

我希望跨多个列合并两个数据框,但有一些附加条件。

import pandas as pd
df1 = pd.DataFrame({
    'col1': ['a','b','c', 'd'],
    'optional_col2': ['X',None,'Z','V'],
    'optional_col3': [None,'def', 'ghi','jkl']
})

df2 = pd.DataFrame({
    'col1': ['a','b','c', 'd'],
    'optional_col2': ['X','Y','Z','W'],
    'optional_col3': ['abc', 'def', 'ghi','mno']
})

我想总是加入,col1然后尝试加入optional_col2optional_col3。在df1中,该值可以NaN用于两列,但始终填充在 中df2。我希望连接在col1+ 之一optional_col2optional_col3匹配时有效。

这将分别由于精确、精确和精确匹配而导致['a', 'b', 'c']加入。col2col3

在 SQL 中,我想你可以这样写连接,如果它有助于进一步解释:

select
    *
from
    df1
        inner join
    df2
        on df1.col1 = df2.col2
        AND (df1.optional_col2 = df2.optional_col2 OR df1.optional_col3 = df2.optional_col3)

我已经搞砸了,pd.merge但无法弄清楚如何进行这样的复杂操作。我想我可以在然后合并上['col1', 'optional_col2']进行第二次合并['col1', 'optional_col_3']并删除重复项?

预期的 DataFrame 将类似于:

merged_df = pd.DataFrame({
    'col1': ['a', 'b', 'c'],
    'optional_col_2': ['X', 'Y', 'Z'],
    'optional_col_3': ['abc', 'def', 'ghi']
})

标签: pythonpandasdataframe

解决方案


此解决方案通过在两个数据帧中创建一个名为“temp”的额外列来工作。其中df11将是一列真实值。df2如果任一可选列之间存在匹配,则in值将为 true。我不清楚您是否认为一个NaN值是可匹配的,如果是这样,那么您需要在比较之前用值填充NaN列的 s以满足您对缺失值的标准(这就是下面的内容)。如果这不是必需的,则在下面的示例中删除呼叫。df1df2fillna

df1["temp"] = True
optional_col2_match = df1["optional_col2"].fillna(df2["optional_col2"]).eq(df2["optional_col2"])
optional_col3_match = df1["optional_col3"].fillna(df2["optional_col3"]).eq(df2["optional_col3"])
df2["temp"] = optional_col2_match | optional_col3_match

然后在合并中使用“temp”列,然后删除它 - 它已经达到了它的目的

pd.merge(df1, df2, on=["col1", "temp"]).drop(columns="temp")

这给出了以下结果

  col1 optional_col2_x optional_col3_x optional_col2_y optional_col3_y
0    a               X             abc               X             abc
1    b               Y             def               Y             def
2    c               Z             ghi               Z             ghi

您需要决定在这里做什么。在您给出的示例中,没有与 和 之一匹配的行optional_col2optional_col2这就是为什么 3 列解决方案看起来合理的原因。一般不会出现这种情况。


推荐阅读