pandas:合并(连接)多列上的两个数据框

问题描述 投票:0回答:6

我正在尝试使用两列连接两个 pandas 数据框:

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]'

知道什么是正确的方法吗?

python python-3.x pandas join pandas-merge
6个回答
618
投票

试试这个

new_df = pd.merge(A_df, 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 使用特定向量作为连接键而不是 栏目

right_on :标签或列表,或要加入的类似数组的字段名称 在右 DataFrame 或每个 left_on 文档的向量/向量列表中


23
投票
  1. 它按照

    left_on
    right_on
    的顺序合并,即
    left_on
    的第i个元素将与
    right_on
    的第i个元素匹配。

    在下面的示例中,顶部的代码将

    A_col1
    B_col1
    匹配,
    A_col2
    B_col2
    匹配,而底部的代码将
    A_col1
    B_col2
    以及
    A_col2
    B_col1
    匹配。显然,结果是不同的。

  2. 从上面的示例可以看出,如果合并键具有不同的名称,则所有键将在合并的数据框中显示为各自的列。在上面的示例中,在顶部数据框中,

    A_col1
    B_col1
    相同,并且
    A_col2
    B_col2
    相同。在底部数据框中,
    A_col1
    B_col2
    相同,并且
    A_col2
    B_col1
    相同。由于这些是重复的列,因此很可能不需要它们。从一开始就避免出现此问题的一种方法是从一开始就使合并键相同。请参阅下面的第 3 点。

  3. 如果

    left_on
    right_on
    是相同的
    col1
    col2
    ,我们可以使用
    on=['col1', 'col2']
    。在这种情况下,合并键不会重复。

    df1.merge(df2, on=['col1', 'col2'])
    

  4. 您还可以合并列名称的一侧和索引的另一侧。例如,在下面的示例中,

    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'])
    

  5. 通过使用

    how=
    参数,您还可以执行
    LEFT JOIN
    (
    how='left'
    )、
    FULL OUTER JOIN
    (
    how='outer'
    ) 和
    RIGHT JOIN
    (
    how='right'
    )。默认值为
    INNER JOIN
    (
    how='inner'
    ),如上面的示例所示。

  6. 如果您有 2 个以上的数据帧要合并,并且所有数据帧的合并键都相同,则

    join
    方法比
    merge
    更有效,因为您可以传递数据帧列表并连接索引。请注意,下例中所有数据帧的索引名称都是相同的(
    col1
    col2
    )。请注意,索引不必有名称;只要有名称即可。如果索引没有名称,则多索引的数量必须匹配(在下面的情况下有 2 个多索引)。同样,如要点 #1 所示,匹配根据索引的顺序进行。

    df1.join([df2, df3], how='inner').reset_index()
    


16
投票

另一种方法:

new_df = A_df.merge(B_df, left_on=['A_c1','c2'], right_on = ['B_c1','c2'], how='left')

15
投票

简短易懂:

merged_data= df1.merge(df2, on=["column1","column2"])

14
投票

这里的问题是,通过使用撇号,您将传递的值设置为字符串,而事实上,正如 @Shijo 在文档中所述,该函数需要一个标签或列表,而不是一个字符串!如果列表包含为左右数据帧传递的每个列的名称,则每个列名称 must 单独位于撇号内。通过以上所述,我们可以理解为什么这是不正确的:

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'])

-1
投票

这对我有用,适用于 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
© www.soinside.com 2019 - 2024. All rights reserved.