在不同的列名上合并两个不同的数据框[重复]
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 本身中为所有列和行读取它时进行了剥离。
超级,还是KeyError
? print (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']
也可以删除,因为B
和CC
中没有匹配项。你也可以添加你的输出吗?
@jezrael 在这种情况下可以删除,但也许 OP 有一些不应该删除的数据:)【参考方案2】:
您还可以将join
与默认左连接或merge
一起使用,如有必要,最后通过dropna
删除带有NaN
s 的行:
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
这种方法是否符合您的要求?
【讨论】:
以上是关于在不同的列名上合并两个不同的数据框[重复]的主要内容,如果未能解决你的问题,请参考以下文章