pandas批量合并CSV文件触发None of [Index]列不存在报错
问题说明
单文件运行正常的pandas CSV合并逻辑,批量运行时在pd.merge()步骤抛出错误:
None of [Index(['status'], dtype='object')] are in the [columns]
单文件测试时代码如下,功能正常:
df1 = pd.read_csv(r'path') df2 = pd.read_csv(r'path') df2 = df2.fillna(0) df3 = pd.merge(df1,df2[['status','stati']].astype(object),on='status', how='left').drop(columns = ['status']) df3.rename({'stati':'status'}, axis=1, inplace=True) df3.to_csv
测试用数据结构:
| df1 | status | df2 | status | stati |
|---|---|---|---|---|
| 0 | A | 0 | A | aktiv |
| 1 | B | 1 | B | beantragt |
| 2 | C | 2 | C | storniert |
| 3 | D | 3 | D | DV |
批量处理代码如下,运行触发上述报错:
dir = r'path' df2 = pd.read_csv(r'path') csv_files = [f for f in Path(dir).glob('*.csv')] for csv in csv_files: df = pd.read_csv(csv) df2 = df2.fillna(0) df3 = pd.merge(df,df2[['status','stati']].astype(object),on='status', how='left').drop(columns = ['status']) df3.rename({'stati':'status'}, axis=1, inplace=True) df3.to_csv
故障原因
批量代码存在4个明确问题,直接或间接触发报错:
- 遍历范围无过滤:
glob('*.csv')会扫描目标目录下所有CSV文件,包括映射表源文件、历史导出的结果文件、同目录下其他不相关CSV,这类文件大多没有status列,单文件测试时手动选择了符合结构的文件,因此不会触发问题。 - 映射表预处理位置错误:
df2.fillna(0)写在循环内部,一旦后续调试时误加inplace=True,或在循环内误修改df2的列结构,会直接破坏映射表,导致后续循环取df2[['status','stati']]时触发列不存在错误。 - 列名隐藏格式问题:批量文件可能存在列名前后带空白字符(如
status、status)、文件头前置空行导致pandas误将数据行识别为表头、编码异常导致列名乱码等情况,这类问题在单个规范文件测试时不会出现。 - 写入逻辑完全失效:
df3.to_csv写在循环外部且未传入保存路径,一方面循环内的处理结果会被逐次覆盖,最终仅保留最后一个文件的处理结果;另一方面无路径的to_csv不会执行任何写入操作,处理结果无法落地。
修复代码
import pandas as pd from pathlib import Path # 路径配置 target_dir = r'待处理CSV文件所在目录' mapping_path = r'映射表CSV的完整路径' # 循环外一次性完成映射表读入和预处理 df_mapping = pd.read_csv(mapping_path) df_mapping = df_mapping[['status', 'stati']].astype(object).fillna(0) # 遍历文件时过滤掉映射表本身,避免将映射表作为待处理文件读入 csv_list = [ f for f in Path(target_dir).glob('*.csv') if f.resolve() != Path(mapping_path).resolve() ] for csv_file in csv_list: # 读文件时跳过空行,兼容头部有空行的异常文件 df = pd.read_csv(csv_file, skip_blank_lines=True) # 统一清理列名前后空白,解决隐藏空格导致的列匹配失败 df.columns = df.columns.str.strip() # 前置校验,无status列的文件直接跳过并打印提示 if 'status' not in df.columns: print(f"跳过文件{csv_file.name}:未找到status列") continue # 执行合并逻辑 df_res = pd.merge( df, df_mapping, on='status', how='left' ).drop(columns=['status']) df_res.rename({'stati': 'status'}, axis=1, inplace=True) # 循环内保存结果,新增_merged后缀避免覆盖原文件 save_path = csv_file.with_name(f"{csv_file.stem}_merged{csv_file.suffix}") df_res.to_csv(save_path, index=False, encoding='utf-8-sig')
排查技巧
如果修改后仍有报错,在pd.merge代码行前添加print(f"当前处理文件:{csv_file.name},列名列表:{df.columns.tolist()}"),即可快速定位异常文件,直接看到实际读取到的列名,排查是否存在列名拼写、空格、编码识别问题。
内容的提问来源于stack exchange,提问作者Anthony Admin
相关产品推荐
相关产品推荐

