拼接多级索引DataFrame时如何保留列的原有顺序?
保留多级索引DataFrame一级索引顺序的拼接方法
问题描述
现有两个多级索引的pandas DataFrame:
import pandas as pd df1 = pd.DataFrame({ ('y1', '0'): [1, 2, 3], ('y2', '0'): [4, 5, 6], ('y11', '0'): [7, 8, 9], }) df2 = pd.DataFrame({ ('y1', '1'): [1.5, 2.5, 3.5], ('y2', '1'): [4.5, 5.5, 6.5], ('y11', '1'): [7.5, 8.5, 9.5], })
期望拼接后得到如下结果,保留一级索引原有顺序y1; y2; y11,同时将同一一级索引下的二级索引(0和1)交错排列:
df = pd.DataFrame({ ('y1', '0'): [1, 2, 3], ('y1', '1'): [1.5, 2.5, 3.5], ('y2', '0'): [4, 5, 6], ('y2', '1'): [4.5, 5.5, 6.5], ('y11', '0'): [7, 8, 9], ('y11', '1'): [7.5, 8.5, 9.5], })
尝试使用pd.concat加sort_index的方式:
df = pd.concat((df1, df2), axis="columns").sort_index(axis="columns")
但会导致一级索引按字典序被打乱为y1、y11、y2,输出结果如下:
y1 y11 y2 0 1 0 1 0 1 0 1 1.5 7 7.5 4 4.5 1 2 2.5 8 8.5 5 5.5 2 3 3.5 9 9.5 6 6.5
需要找到更优的解决方案,避免复杂正则处理。
解决方案
方法1:基于原一级索引顺序重排列
先拼接两个DataFrame,再利用df1的一级索引原始顺序,重新构造列的排列顺序:
# 拼接两个DataFrame combined = pd.concat([df1, df2], axis=1) # 获取df1中一级索引的原始唯一顺序 first_level_order = df1.columns.get_level_values(0).unique() # 遍历每个一级索引,收集对应的所有二级索引列 target_columns = [] for level1 in first_level_order: target_columns.extend([col for col in combined.columns if col[0] == level1]) # 按目标顺序重新排列列 df = combined[target_columns]
方法2:通过join合并后重排列
由于两个DataFrame行索引一致,可直接用join合并,再按同样逻辑调整列顺序:
# 合并DataFrame combined = df1.join(df2) # 获取一级索引原始顺序 first_level_order = df1.columns.get_level_values(0).unique() # 构造目标列顺序 target_columns = [] for level1 in first_level_order: target_columns.extend([col for col in combined.columns if col[0] == level1]) # 重排列 df = combined[target_columns]
方法3:构造目标MultiIndex后重索引
若已知二级索引的所有取值(此处为['0','1']),可直接构造目标列的MultiIndex,再对拼接后的DataFrame重索引:
# 拼接得到完整数据集 combined = pd.concat([df1, df2], axis=1) # 构造目标列的MultiIndex target_index = pd.MultiIndex.from_product( [df1.columns.get_level_values(0).unique(), ['0', '1']], names=combined.columns.names ) # 按目标索引重排列 df = combined.reindex(target_index, axis=1)
内容的提问来源于stack exchange,提问作者Sai-Aakash Ramesh
相关产品推荐
相关产品推荐

