将Pandas多索引列DataFrame转换为无重复列的单索引DataFrame
解决Pandas对比DataFrame时空结果的列格式问题
问题分析
当两个DataFrame完全相同时,现有代码生成的结果会保留(列名, old)和(列名, new)的多层列索引(MultiIndex),但实际需要的是单层的原始列名。
修改方案
在生成changed_data之后,添加一段代码处理列名:判断列是否为多层索引,若是则提取每个列元组的第一个元素,去重后作为新列名。
修改后的完整代码:
import pandas as pd import numpy as np before_df = pd.DataFrame(data= {'col1':[1,2,3,4], 'col2':['A','B','C','D'], 'amount': [12, 21,31,51]}) after_df = pd.DataFrame(data= {'col1':[1,2,3,4], 'col2':['A','B','C','D'], 'amount': [12, 21,31,51]}) config_index = ['col1'] before_df = before_df.set_index(config_index) after_df = after_df.set_index(config_index) before_keys = before_df.index after_keys = after_df.index common_keys = np.intersect1d(before_keys, after_keys, assume_unique=True) common_columns = np.intersect1d(before_df.columns, before_df.columns, assume_unique=True) before_common = before_df.loc[common_keys, common_columns] after_common = after_df.loc[common_keys, common_columns] common_data = pd.concat([before_common.reset_index(), after_common.reset_index()], sort=True) changed_keys = common_data.drop_duplicates(keep=False) changed_keys = changed_keys[config_index] changed_keys = changed_keys.set_index(config_index).index change_df = pd.concat([before_common.loc[changed_keys], after_common.loc[changed_keys]], axis='columns', keys=['old', 'new']) change_df_swap = change_df.swaplevel(axis='columns') changed_df_group = change_df_swap.groupby(level=0, axis='columns') changed_data = changed_df_group.apply(lambda frame: frame.apply(lambda x: x.iloc[0] if x.iloc[0] == x.iloc[1] else f'{x.iloc[0]} ---> {x.iloc[1]}', axis='columns')) # 新增处理列名的代码 if isinstance(changed_data.columns, pd.MultiIndex): # 提取MultiIndex的第一层,去重后作为新列名 changed_data.columns = changed_data.columns.get_level_values(0).unique() print(changed_data)
效果验证
运行修改后的代码,输出将变为:
Empty DataFrame Columns: [amount, col2] Index: []
完全符合期望输出。
补充说明
这段新增代码会自动适配两种场景:
- 当DataFrame存在差异时,
changed_data的列已经是单层格式,不会触发修改; - 当DataFrame完全相同时,会将多层索引的列名简化为原始的单层列名。
内容的提问来源于stack exchange,提问作者CNKR
相关产品推荐
相关产品推荐

