pandas:在多列上合并(连接)两个数据框
- 2025-02-12 10:03:00
- admin 原创
- 58
问题描述:
我正在尝试使用两列连接两个熊猫数据框:
new_df = pd.merge(A_df, B_df, how='left', left_on='[A_c1,c2]', right_on = '[B_c1,c2]')
但出现以下错误:
pandas/index.pyx in pandas.index.IndexEngine.get_loc (pandas/index.c:4164)()
pandas/index.pyx in pandas.index.IndexEngine.get_loc (pandas/index.c:4028)()
pandas/src/hashtable_class_helper.pxi in pandas.hashtable.PyObjectHashTable.get_item (pandas/hashtable.c:13166)()
pandas/src/hashtable_class_helper.pxi in pandas.hashtable.PyObjectHashTable.get_item (pandas/hashtable.c:13120)()
KeyError: '[B_1, c2]'
知道正确的做法是什么吗?
解决方案 1:
尝试一下
new_df = pd.merge(
left=A_df,
right=B_df,
how='left',
left_on=['A_c1', 'c2'],
right_on=['B_c1', 'c2'],
)
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html
left_on:标签或列表,或类似数组的字段名称,用于在左侧 DataFrame 中连接。可以是 DataFrame 长度的向量或向量列表,以使用特定向量作为连接键,而不是列
right_on:标签或列表,或类似数组的字段名称,用于在右侧 DataFrame 或每个 left_on 文档的向量/向量列表中加入
解决方案 2:
它按照
left_on
和的顺序进行合并right_on
,即 的第 i 个元素left_on
将与 的第 i 个元素匹配right_on
。
下面的例子中,上面的代码A_col1
与B_col1
和A_col2
匹配B_col2
,而下面的代码A_col1
与B_col2
和A_col2
匹配B_col1
。显然,结果是不同的。
从上面的示例可以看出,如果合并键具有不同的名称,则所有键都将在合并的数据框中显示为各自的列。在上面的示例中,在顶部数据框中,
A_col1
和B_col1
是相同的,并且A_col2
和B_col2
是相同的。在底部数据框中,A_col1
和B_col2
是相同的,并且A_col2
和B_col1
是相同的。由于这些是重复的列,因此很可能不需要它们。从一开始就避免出现此问题的一种方法是从一开始就使合并键相同。请参阅下面的要点 #3。如果
left_on
和right_on
相同col1
且col2
,我们可以使用on=['col1', 'col2']
。在这种情况下,没有重复的合并键。
df1.merge(df2, on=['col1', 'col2'])
您还可以根据列名合并一侧,根据索引合并另一侧。例如,在下面的示例中,
df1
的列与df2
的索引匹配。如果索引已命名(如下例所示),则您可以按名称引用它们,但如果没有,您也可以使用right_index=True
(或者left_index=True
如果左侧数据框是根据索引合并的数据框)。
df1.merge(df2, left_on=['A_col1', 'A_col2'], right_index=True)
# or
df1.merge(df2, left_on=['A_col1', 'A_col2'], right_on=['B_col1', 'B_col2'])
通过使用参数,您还
how=
可以执行LEFT JOIN
(how='left'
)、FULL OUTER JOIN
(how='outer'
)和RIGHT JOIN
( )。如上例所示,默认值为( )。how='right'
`INNER JOIN`how='inner'
如果您有 2 个以上的数据框需要合并,并且所有数据框的合并键都相同,则
join
方法比 更有效,merge
因为您可以传递数据框列表并加入索引。请注意,以下示例中所有数据框的索引名称都相同(col1
和col2
)。请注意,索引不必有名称;如果索引没有名称,则多索引的数量必须匹配(在下面的情况下有 2 个多索引)。同样,如要点 #1 中所述,匹配根据索引的顺序进行。
df1.join([df2, df3], how='inner').reset_index()
解决方案 3:
简短易懂:
merged_data= df1.merge(df2, on=["column1","column2"])
解决方案 4:
另一种方法:
new_df = A_df.merge(B_df, left_on=['A_c1','c2'], right_on = ['B_c1','c2'], how='left')
解决方案 5:
这里的问题是,通过使用撇号,您将传递的值设置为字符串,而事实上,正如@Shijo 在文档中所述,该函数需要标签或列表,而不是字符串!如果列表包含传递到左侧和右侧数据框的每个列的名称,则每个列名都必须单独位于撇号内。根据上述内容,我们可以理解为什么这是错误的:
new_df = pd.merge(A_df, B_df, how='left', left_on='[A_c1,c2]', right_on = '[B_c1,c2]')
这是使用该函数的正确方法:
new_df = pd.merge(A_df, B_df, how='left', left_on=['A_c1','c2'], right_on = ['B_c1','c2'])
解决方案 6:
这对我有用,适用于 n 个文件 xls
# all_reports_paths contain one array with all paths per files
for a in all_reports_paths:
df.append( pd.read_excel(a,skiprows=X,skipfooter=X))
df_glob = pd.DataFrame(columns=columns)
for dataframe in df:
df_glob = pd.concat([df_glob,pd.DataFrame(dataframe)],axis=0)
# finally df_glob contain all data