在不同的列名上合并两个不同的数据框[重复]

Posted

技术标签:

【中文标题】在不同的列名上合并两个不同的数据框[重复]【英文标题】:Merge two different dataframes on different column names [duplicate] 【发布时间】:2017-09-29 19:33:01 【问题描述】:

我有两个数据框,

df1 = pd.DataFrame('A': ['A1', 'A1', 'A2', 'A3'],
                     'B': ['121', '345', '123', '146'],
                     'C': ['K0', 'K1', 'K0', 'K1'])

df2 = pd.DataFrame('A': ['A1', 'A3'],
                      'BB': ['B0', 'B3'],
                      'CC': ['121', '345'],
                      'DD': ['D0', 'D1'])

现在我需要从 df1 的 A 列和 B 列以及 df2 的 A 列和 CC 列获取类似的行。 所以我尝试了可能的合并选项,例如:

both_DFS=pd.merge(df1,df2, how='left',left_on=['A','B'],right_on=['A','CC'])

这不会给我来自 df2 数据帧的行信息,这是我需要的。意思是,我有 df2 中的所有列名,但行只是空的或 Nan。

然后我尝试了:

Both_DFs=pd.merge(df1,df2, how='left',left_on=['A','B'],right_on=['A','CC'])[['A','B','CC']]

这给了我错误,

KeyError: "['B'] not in index"

我的目标是拥有一个包含 df1 和 df2 的所有列的合并数据框。任何建议都会很棒

期望的输出:

 Both_DFs
    A   B   C   BB  CC  DD
0   A1  121 K0  B0  121 D0

所以在我的数据帧(df1 和 df2)中,只有一行与感兴趣的两列完全匹配。也就是说,df1 中的 A 列和 B 列只有一行与 df2 中的 A 列和 CC 列中的行完全匹配

【问题讨论】:

print (df1.columns.tolist()) 是什么?问题只出在真实数据上? 因为似乎只有列名中有一些空格,用于消除需要df.columns = df.columns.str.strip() 实际数据农场有另一个列名,我的问题中使用的 df1 是虚拟的。因此,使用我的实际数据农场,它会打印出 ['Chr', 'Start', 'End', 'Annotation', 'Detailed Annotation', 'Description', 'Type'] for (df1.columns.tolist()) @jezrael 我在 pd.read_csv 本身中为所有列和行读取它时进行了剥离。 超级,还是KeyErrorprint (df2.columns.tolist()) 可能有问题吗? 【参考方案1】:

好吧,如果您将列 A 声明为索引,它会起作用:

Both_DFs = pd.merge(df1.set_index('A', drop=True),df2.set_index('A', drop=True), how='left',left_on=['B'],right_on=['CC'], left_index=True, right_index=True).dropna().reset_index()

这会导致:

    A    B   C  BB   CC  DD
0  A1  123  K0  B0  121  D0
1  A1  345  K1  B0  121  D0
2  A3  146  K1  B3  345  D1

编辑

你只需要:

Both_DFs = pd.merge(df1,df2, how='left',left_on=['A','B'],right_on=['A','CC']).dropna()

这给出了:

    A    B   C  BB   CC  DD
0  A1  121  K0  B0  121  D0

【讨论】:

它合并了右列,但问题是一样的,对于正确的数据框 df2,Both_DFs 中的列只是空的或 Nan。 df1 中的一些行已合并到 Both_DFs 数据帧,与我上面的脚本相同。 df2 的列在那里,但行只是空的 进行了编辑,似乎有效:) 是的,成功了 :) 谢谢 @zipa - 我认为left_on=['B'],right_on=['CC'] 也可以删除,因为BCC 中没有匹配项。你也可以添加你的输出吗? @jezrael 在这种情况下可以删除,但也许 OP 有一些不应该删除的数据:)【参考方案2】:

您还可以将join 与默认左连接或merge 一起使用,如有必要,最后通过dropna 删除带有NaNs 的行:

print (df1.join(df2.set_index('A'), on='A').dropna())
    A    B   C  BB   CC  DD
0  A1  123  K0  B0  121  D0
1  A1  345  K1  B0  121  D0
3  A3  146  K1  B3  345  D1

print (pd.merge(df1, df2, on='A', how='left').dropna())
    A    B   C  BB   CC  DD
0  A1  123  K0  B0  121  D0
1  A1  345  K1  B0  121  D0
3  A3  146  K1  B3  345  D1

编辑:

我认为您需要inner join(默认情况下,可以省略on='inner'):

Both_DFs = pd.merge(df1,df2, left_on=['A','B'],right_on=['A','CC'])
print (Both_DFs)
    A    B   C  BB   CC  DD
0  A1  121  K0  B0  121  D0

【讨论】:

看来您只需要删除how='left' 即可进行默认内连接。【参考方案3】:

我不知道您的示例是否完全显示了您的问题,但是,

如果我们尝试与 MultiIndex 合并,我们需要有 2 个索引匹配。

df1['A'] == df2['A'] && df1['B'] == df2['CC']

这里我们没有任何与 2 索引匹配的行。

如果我们仅通过 df1['A'] 合并,我们会得到如下结果: Both_DFs=pd.merge(df1, df2, how='left', left_on=['A'], right_on=['A'])

    A    B   C   BB   CC   DD
0  A1  123  K0   B0  121   D0
1  A1  345  K1   B0  121   D0
2  A2  121  K0  NaN  NaN  NaN
3  A3  146  K1   B3  345   D1

如果您不想删除不在 df2 中的行,请尝试将 'how' 方法更改为内部。

Both_DFs=pd.merge(df1, df2, how='left', left_on=['A'], right_on=['A'])
   A    B   C   BB   CC   DD
0  A1  123  K0   B0  121   D0
1  A1  345  K1   B0  121   D0
2  A3  146  K1   B3  345   D1

这种方法是否符合您的要求?

【讨论】:

以上是关于在不同的列名上合并两个不同的数据框[重复]的主要内容,如果未能解决你的问题,请参考以下文章

合并两个具有相同列名但在熊猫中列数不同的数据框

熊猫合并:合并同一列上的两个数据框,但保留不同的列

Pandas 合并具有不同列的两个数据框

Python合并两个具有不同日期时间的数据框[重复]

每次合并具有不同列名的熊猫数据框列表

在具有不同列名的pandas中连接2个数据帧[重复]