在使用Pandas进行数据处理时,合并多个DataFrame是高频操作,但合并后的列顺序通常按照合并逻辑自动排列,往往不符合实际分析或下游任务的要求,因此需要手动精确调整列顺序。

合并DataFrame后列顺序的常见问题
当使用concat或merge合并DataFrame时,列顺序的默认规则如下:
- 使用
concat纵向合并时,列顺序按照第一个DataFrame的列顺序排列,后续DataFrame中不存在的列会补为缺失值 - 使用
merge横向合并时,列顺序先展示连接键,再依次展示左表和右表的其余列
这些默认规则很难匹配实际业务需求,比如我们需要把核心指标列放在最前面,或者按照特定的业务逻辑排列列顺序。
方法一:直接指定列名列表重排
这是最直接的方法,合并完成后,直接通过列名列表对DataFrame进行切片,就可以得到指定顺序的列。首先需要获取合并后DataFrame的所有列名,再按照需求调整顺序,最后用调整后的列名列表重新索引DataFrame。
以下是具体的代码示例:
import pandas as pd
# 构造两个测试DataFrame
df1 = pd.DataFrame({
'id': [1, 2, 3],
'name': ['张三', '李四', '王五'],
'age': [20, 25, 30]
})
df2 = pd.DataFrame({
'id': [1, 2, 3],
'score': [85, 90, 88],
'class': ['一班', '一班', '二班']
})
# 使用merge合并DataFrame
merged_df = pd.merge(df1, df2, on='id')
print('合并后的默认列顺序:')
print(merged_df.columns.tolist())
# 指定需要的列顺序
target_columns = ['id', 'name', 'class', 'age', 'score']
# 重排列顺序
reordered_df = merged_df[target_columns]
print('重排后的列顺序:')
print(reordered_df.columns.tolist())
print(reordered_df)
方法二:基于列名规则动态排序
如果列数量较多,或者列名存在统一的前缀、后缀规则,可以通过自定义排序函数动态生成目标列名列表,避免手动逐个写列名。
比如我们需要把所有以base_开头的列放在最前面,其余列按字母顺序排列,实现代码如下:
import pandas as pd
# 构造测试DataFrame
df = pd.DataFrame({
'user_id': [1, 2],
'base_name': ['张三', '李四'],
'base_age': [20, 25],
'ext_score': [85, 90],
'ext_level': ['A', 'B']
})
# 获取所有列名
all_columns = df.columns.tolist()
# 分为基础列和其馀列
base_cols = [col for col in all_columns if col.startswith('base_')]
other_cols = [col for col in all_columns if not col.startswith('base_')]
# 按字母顺序排序其馀列
other_cols_sorted = sorted(other_cols)
# 拼接目标列顺序
target_columns = base_cols + other_cols_sorted
# 重排列
reordered_df = df[target_columns]
print('动态排序后的列顺序:')
print(reordered_df.columns.tolist())
方法三:合并时提前定义列顺序
如果可以在合并前就明确最终的列顺序,也可以在合并前先调整单个DataFrame的列顺序,合并后的结果会优先沿用第一个DataFrame的列顺序(针对concat场景),或者手动指定合并后的列顺序。
以concat纵向合并为例,提前调整列顺序的代码如下:
import pandas as pd
df1 = pd.DataFrame({
'id': [1, 2],
'name': ['张三', '李四'],
'age': [20, 25]
})
df2 = pd.DataFrame({
'id': [3, 4],
'age': [22, 28],
'name': ['王五', '赵六']
})
# 提前调整df2的列顺序和df1一致
df2 = df2[['id', 'name', 'age']]
# 纵向合并
merged_df = pd.concat([df1, df2], ignore_index=True)
print('提前调整顺序后合并的列顺序:')
print(merged_df.columns.tolist())
print(merged_df)
注意事项
重排列顺序时需要注意以下几点:
- 指定的列名必须全部存在于DataFrame中,否则会抛出
KeyError错误,如果不确定列是否存在,可以先做存在性校验 - 如果有不需要展示的列,可以从目标列名列表中剔除,实现列的筛选和排序同步完成
- 对于超大DataFrame,直接列切片的操作效率很高,不会带来额外的性能损耗
调整列顺序的本质是对DataFrame的列索引进行重新排序,核心逻辑就是通过列名列表对原DataFrame进行列维度的切片操作,掌握这个核心逻辑后可以灵活适配各种排序场景。