如何将两个列名唯一的Pandas DataFrame上下堆叠且不丢失列名?
解决方法:手动对齐列数并插入表头行
你遇到的问题核心在于pd.concat默认会按列名对齐数据,而你的两个DataFrame列名完全不重叠,所以它会自动合并所有列,导致DF1的行在DF2的列位上显示NaN,反之亦然。但你想要的是「原样堆叠」——就像复制粘贴表格一样,不管列名,只按行的顺序堆叠,同时保留DF2的列名作为一行插入。
下面是具体的实现步骤:
步骤1:还原你的原始DataFrame
先把你描述的DataFrame正确构造出来(原始排版有点小问题,我按内容还原):
import pandas as pd # DF1:2列,3行数据 df1 = pd.DataFrame([['A', 'C'], ['B', 'D'], ['X', 'Y']], columns=['Col1', 'Col1_2']) # DF2:4列,3行数据 df2 = pd.DataFrame([['a', 'c', 'x', 't'], ['b', 'd', 'y', 'j'], ['b', 'e', 'z', 'k']], columns=['Col2', 'Col3', 'Col4', 'Col5'])
步骤2:实现「复制粘贴式」堆叠逻辑
我们需要先把两个DataFrame的行都对齐到最大列数,然后插入DF2的列名作为一行,最后拼接所有部分:
# 计算两个DataFrame的最大列数,确定最终表格的列数 max_columns = max(df1.shape[1], df2.shape[1]) # 处理DF1:把每行补NaN到最大列数,保证和DF2的列数匹配 df1_processed = pd.DataFrame( [list(row) + [pd.NA] * (max_columns - df1.shape[1]) for _, row in df1.iterrows()] ) # 创建DF2的表头行:把DF2的列名作为一行数据 df2_header = pd.DataFrame([df2.columns.tolist()]) # 处理DF2:本身列数等于最大列数,直接转换即可 df2_processed = pd.DataFrame([list(row) for _, row in df2.iterrows()]) # 拼接所有部分,重置行索引 final_result = pd.concat([df1_processed, df2_header, df2_processed], ignore_index=True)
步骤3:查看最终结果
运行后final_result的输出就和你预期的完全一致了:
0 1 2 3 0 A C <NA> <NA> 1 B D <NA> <NA> 2 X Y <NA> <NA> 3 Col2 Col3 Col4 Col5 4 a c x t 5 b d y j 6 b e z k
如果需要给最终表格统一命名列(比如都用Col1、Col2这类格式),可以直接修改列名:
final_result.columns = [f'Col{i+1}' for i in range(max_columns)]
这样就完美实现了「不按列名匹配,直接上下堆叠」的需求,完全保留了原始数据的行顺序和DF2的列名,没有丢失任何内容。
内容的提问来源于stack exchange,提问作者Baran Aldemir
相关产品推荐
相关产品推荐

