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

Pandas批量处理CSV报KeyError指定列不存在问题排查

问题根因

报错和glob本身无关,是代码逻辑错误导致的,具体问题点:

  • 代码拆成了两个独立的for fp in files循环,逻辑完全断裂:第一个循环仅逐个读取CSV,df.to_csv没有加括号、没有传入输出参数,根本不会执行写入,读完的df也没有做任何持久化保存。第一个循环结束后,df变量仅保留最后一次遍历到的文件内容,第二个循环遍历文件列表时,根本没有重新读取当前路径对应的文件,全程在反复操作同一个残留的df对象。
  • 触发KeyError的直接原因:glob.glob()的匹配范围包含了你用来做映射的df2源文件。第一个循环读取到这个映射文件时,强行通过names参数给它指定了业务表的29个固定列名,直接覆盖了映射表原本的status/stati/sparte/sparten等列结构,等执行df2[['status','stati']]选取列时,df2的列已经被篡改,自然找不到对应列。单文件测试时不会把映射表本身作为待处理文件读入覆盖结构,所以可以正常运行。
  • 其他隐藏bug:第二个循环里每次迭代都执行df2 = df2.fillna(0)属于无意义重复操作;最后关联gesellschaft字段时right_on直接传入了Series对象而非列名,运行到该步会触发新的报错;所有to_csv调用都没有实际执行,不会生成结果文件。
修复方案
  1. 合并两个拆分的循环,每个文件的读取、转换、写入在单次循环内完成
  2. 增加过滤逻辑,避免glob把映射表文件纳入待处理列表
  3. 修正merge参数错误,补全文件写入逻辑

修复后可直接运行的代码:

import glob
import pandas as pd
import os

# 读取映射表,该文件不要放在待处理CSV的目录下,避免被glob误匹配
df2 = pd.read_csv(r'映射表CSV的完整路径')
df2 = df2.fillna(0) # 映射表空值填充仅需执行一次,不要放在循环内

# 匹配所有待处理CSV
files = glob.glob(r'待处理CSV所在目录\*.csv')
# 保险过滤:如果映射表和待处理文件在同目录,手动排除
map_file_abs = os.path.abspath(r'映射表CSV的完整路径')
files = [fp for fp in files if os.path.abspath(fp) != map_file_abs]

for fp in files:
    # 读取当前待处理业务文件
    df = pd.read_csv(
        fp,
        names=["vermittler", "vermittler 2", "vermittler 3", "kunde", "nachname", "vorname", "strasse", "plz", "ort", "geburtsdatum", "beruf", "land", "per_du", "login", "login 2", "nationalitaet", "rechtsform", "id", "versicherungsscheinnummer", "sparte", "gesellschaft", "zahlweise", "beginn", "ablauf", "beitrag_netto", "status", "risiko", "antragsdatum", "stornodatum"],
        sep=',',
        on_bad_lines='skip'
    )
    df = df.fillna(0)
    df['gesellschaft'] = df['gesellschaft'].astype(object)

    # 关联status字段映射
    df3 = pd.merge(
        df,
        df2[['status', 'stati']].astype(object),
        on='status',
        how='left'
    ).drop(columns=['status'])
    df3.rename({'stati': 'status'}, axis=1, inplace=True)

    # 关联sparte字段映射
    df4 = df3.merge(
        df2[['sparte', 'sparten']].astype(object),
        on='sparte',
        how='left'
    ).drop(columns=['sparte'])
    df4.rename({'sparten': 'sparte'}, axis=1, inplace=True)

    # 关联gesellschaft字段映射,修正原right_on传参错误
    df5 = df4.merge(
        df2[['gesellschaft', 'gesellschaften']].astype(object),
        on='gesellschaft',
        how='left'
    ).drop(columns=['gesellschaft'])
    df5.rename({'gesellschaften': 'gesellschaft'}, axis=1, inplace=True)

    # 写入处理后的文件,默认保存在原目录,文件名加_processed后缀
    output_path = fp.replace('.csv', '_processed.csv')
    df5.to_csv(output_path, index=False, encoding='utf-8-sig')
验证要点
  • 循环内每次重新读取当前遍历到的文件,不会出现变量残留问题
  • 映射表仅读取一次,不会被业务文件的读取逻辑篡改列结构
  • 所有字段关联逻辑和单文件测试逻辑完全一致,不会出现行为差异
  • 补全了文件写入逻辑,处理完成后会在原目录生成对应结果文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:21:13