如何对齐两个DataFrame列并保留原有顺序(非字典序重排)
解决方案
场景分析
你需要合并两个DataFrame的列,同时满足:
- 保留所有唯一列(包含旧版本A的已删除列、新版本B的新增列)
- 自定义列顺序(如示例中的
Hello、Foo、Bar、Hey、Doo、World、Star),而非align方法默认的字典序
代码实现
首先定义列集合:
import pandas as pd # 旧版本A的列 cols_a = ['Hello', 'Foo', 'Hey', 'Bar', 'World'] # 新版本B的列 cols_b = ['Hello', 'Bar', 'Doo', 'World', 'Star']
方案1:匹配示例要求的顺序
该方案以新版本B的列顺序为框架,将旧版本A独有的列插入到它们在A中相对共有列的位置:
# 初始化结果为B的列顺序 result = cols_b.copy() # 筛选A中独有的列(按A的顺序) unique_a_cols = [col for col in cols_a if col not in cols_b] for col in unique_a_cols: # 获取该列在A中的索引 idx_in_a = cols_a.index(col) # 查找左侧最近的共有列 left_shared = None for i in range(idx_in_a - 1, -1, -1): if cols_a[i] in cols_b: left_shared = cols_a[i] break # 查找右侧最近的共有列 right_shared = None for i in range(idx_in_a + 1, len(cols_a)): if cols_a[i] in cols_b: right_shared = cols_a[i] break # 确定插入位置 if left_shared: left_idx = result.index(left_shared) if right_shared: right_idx = result.index(right_shared) insert_pos = left_idx + 1 if (left_idx + 1) < right_idx else right_idx else: insert_pos = left_idx + 1 elif right_shared: insert_pos = result.index(right_shared) else: insert_pos = 0 # 插入列(避免重复) if col not in result: result.insert(insert_pos, col) print(result) # 输出: ['Hello', 'Foo', 'Bar', 'Hey', 'Doo', 'World', 'Star']
方案2:优先保留旧版本A的顺序,追加新版本B的新增列
如果需求是先按A的顺序保留所有旧列,再按B的顺序追加新增列,代码更简洁:
# 先取A的所有列,再添加B中未在A出现的列(按B的顺序) result = cols_a + [col for col in cols_b if col not in cols_a] print(result) # 输出: ['Hello', 'Foo', 'Hey', 'Bar', 'World', 'Doo', 'Star']
应用到DataFrame
得到目标列顺序后,即可重新排列DataFrame的列(以合并A和B的DataFrame为例):
# 假设df_a是旧版本DataFrame,df_b是新版本DataFrame df_combined = pd.concat([df_a, df_b], axis=0, ignore_index=True) # 按目标顺序重排列 df_c = df_combined[result]
内容的提问来源于stack exchange,提问作者ramech
相关产品推荐
相关产品推荐

