如何对含多索引列的两个pandas DataFrame执行外连接合并?
如何对含多索引列的Pandas DataFrame按指定列执行外连接?
当两个Pandas DataFrame都包含多索引列时,如何以双方共有的某一列作为键执行外连接(outer merge)?以下是极简示例代码及运行后出现的错误:
import pandas as pd # 带多索引列的示例DataFrame data1 = { ('A', 'X'): [1, 2, 3], ('A', 'Y'): [4, 5, 6], ('B', 'X'): [7, 8, 9], ('B', 'Y'): [10, 11, 12], } data2 = { ('A', 'X'): [13, 14, 15], ('A', 'Y'): [16, 17, 18], ('B', 'X'): [19, 20, 21], ('B', 'Y'): [22, 23, 24], } df1 = pd.DataFrame(data1, index=['row1', 'row2', 'row3']) df2 = pd.DataFrame(data2, index=['row1', 'row2', 'row3']) # 尝试以('A', 'X')列为键合并 column_to_merge_on = ('A', 'X') merged_df = pd.merge(df1, df2, left_on=column_to_merge_on, right_on=column_to_merge_on) print(merged_df)
运行后报错:
ValueError: 列标签'A'不唯一。 对于多索引,标签必须是与每个层级对应的元组。
解决方法
方法一:将连接列转为索引后合并(兼容性强)
把用于连接的多索引列转为DataFrame的索引,通过索引执行外连接,最后再还原该列:
import pandas as pd data1 = { ('A', 'X'): [1, 2, 3], ('A', 'Y'): [4, 5, 6], ('B', 'X'): [7, 8, 9], ('B', 'Y'): [10, 11, 12], } data2 = { ('A', 'X'): [13, 14, 15], ('A', 'Y'): [16, 17, 18], ('B', 'X'): [19, 20, 21], ('B', 'Y'): [22, 23, 24], } df1 = pd.DataFrame(data1, index=['row1', 'row2', 'row3']) df2 = pd.DataFrame(data2, index=['row1', 'row2', 'row3']) column_to_merge_on = ('A', 'X') # 将连接列设为索引 df1_temp = df1.set_index(column_to_merge_on) df2_temp = df2.set_index(column_to_merge_on) # 执行外连接,合并后重置索引恢复原列 merged_df = pd.merge(df1_temp, df2_temp, left_index=True, right_index=True, how='outer').reset_index() print(merged_df)
方法二:直接使用on参数指定多索引列(需Pandas 1.5.0+)
在较新版本的Pandas中,可以直接将多索引列的元组放入on参数列表,配合how='outer'执行外连接:
import pandas as pd data1 = { ('A', 'X'): [1, 2, 3], ('A', 'Y'): [4, 5, 6], ('B', 'X'): [7, 8, 9], ('B', 'Y'): [10, 11, 12], } data2 = { ('A', 'X'): [13, 14, 15], ('A', 'Y'): [16, 17, 18], ('B', 'X'): [19, 20, 21], ('B', 'Y'): [22, 23, 24], } df1 = pd.DataFrame(data1, index=['row1', 'row2', 'row3']) df2 = pd.DataFrame(data2, index=['row1', 'row2', 'row3']) column_to_merge_on = ('A', 'X') # 直接指定多索引列作为连接键,执行外连接 merged_df = pd.merge(df1, df2, on=[column_to_merge_on], how='outer') print(merged_df)
内容的提问来源于stack exchange,提问作者Jan Willem
相关产品推荐
相关产品推荐

