You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas concat拼接DataFrame时莫名多出全NaN重复列如何解决

问题根因

这是非常典型的列名隐藏字符问题,和DataFrame列数无关。
你看到的“所有表列头完全一致”只是视觉上的一致:至少有一个DataFrame的Article ID列名带了肉眼看不到的字符,最常见的是首尾多了空格、制表符,或是爬取RSS内容时混入了零宽空格、全角空格这类不可见特殊字符。
pd.concat()是严格按列名字符串的精确值做对齐拼接的,只要列名的字符串值不完全相等,哪怕视觉上看不出区别,也会被识别成两个独立列。匹配不到对应列的行位置会自动填充NaN,最终就会出现你看到的“多了一个同名空列”的现象。
之前用shape只能确认每个表的列数量是8,根本检测不到列名里的隐藏字符,自然查不出问题。

排查方法

直接打印每个DataFrame列名的原始表示,就能立刻定位到隐藏字符的位置,运行以下代码即可:

for idx, df in enumerate(frames):
    print(f"===== 第{idx+1}个DataFrame的列名 =====")
    print([repr(col) for col in df.columns])

输出结果里你肯定能看到至少一个Article ID的打印结果和其他的存在差异,比如显示为'Article ID '(末尾多空格)、'Article\u3000ID'(中间为全角空格)这类形式。

解决方案

最稳妥、零踩坑的方案是直接给所有待拼接的DataFrame强制赋值标准列名——既然你已经确认所有表的列顺序、字段含义完全一致,根本不需要纠结列名里藏了什么特殊字符,直接覆盖列名的效率最高,还能顺便避免其他列出现同类问题:

# 定义标准列名,顺序和现有表的列顺序严格对应
standard_columns = ["Source", "Tags", "Date", "Title", "Summary", "Link", "Article ID", "Article Text"]
# 遍历重设所有DataFrame的列名
for i in range(len(frames)):
    frames[i].columns = standard_columns
# 拼接时加上ignore_index=True重置行索引,避免行索引重复
result_df = pd.concat(frames, ignore_index=True)

如果你不想强制覆盖列名,也可以批量清洗所有列名的首尾空白、移除常见特殊字符后再拼接:

for i in range(len(frames)):
    # 去除列名首尾所有空白字符
    frames[i].columns = frames[i].columns.str.strip()
    # 如果排查出有零宽空格类特殊字符,再加一行替换规则即可
    # frames[i].columns = frames[i].columns.str.replace(r'[\u200b\u200c\u200d\ufeff]', '', regex=True)

内容的提问来源于stack exchange,提问作者dbgg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:57:15