Python合并多个CSV文件时如何为每行添加对应来源文件名
合并CSV并新增来源文件名列的实现方案
现有代码的核心问题
当前的逐行复制逻辑存在三个关键缺陷,无法满足需求:
- 仅做纯文本行追加,没有为每行数据追加对应的来源文件名信息
- 未跳过每个源CSV自带的表头行,合并后会在数据中间插入大量重复的
A B C表头内容 - 未提前定义包含
Name列的总表头,文件结构和预期不符
需要补充的核心逻辑
要实现目标,需要在循环遍历每个CSV的环节补充三个固定步骤:
- 提取当前遍历CSV的文件名,去掉
.csv后缀作为来源标识值 - 仅在第一次写入文件时,输出一次追加了
Name字段的总表头,后续不再重复写表头 - 跳过源文件自带的表头行,给每一行有效数据的末尾拼接对应来源标识
具体实现方案
方案1:基于现有原生逐行写入逻辑修改
不需要引入额外依赖的逻辑适配(注意需补充os模块用于文件名解析):
import os from glob import glob header_written = False # 用w模式清空之前生成的错误main.csv,避免旧数据干扰 with open('/opt/home/main.csv', 'w', encoding='utf-8') as singleFile: for csv_path in glob('*.csv'): # 跳过目标输出文件本身,避免把main.csv也遍历进去 if csv_path == 'main.csv': continue # 提取不带.csv后缀的文件名,如XCV123.csv -> XCV123 source_tag = os.path.splitext(os.path.basename(csv_path))[0] with open(csv_path, 'r', encoding='utf-8') as f: lines = f.readlines() # 首次写入时输出带Name列的总表头 if not header_written: singleFile.write(lines[0].strip() + f' Name\n') header_written = True # 跳过源文件自带的表头,逐行追加来源标识 for line in lines[1:]: singleFile.write(line.strip() + f' {source_tag}\n')
注意:如果你的CSV是逗号分隔格式,需要将拼接的分隔符从空格改为逗号,即替换为
f',{source_tag}',保证列分隔规则和原文件一致。
方案2:基于已导入的pandas实现(更稳妥)
利用pandas自动处理列对齐、分隔符识别,避免手动拼接带来的错位、编码问题:
import pandas as pd from glob import glob import os df_list = [] for csv_path in glob('*.csv'): if csv_path == 'main.csv': continue # 读取CSV,原文件为空格分隔时添加sep='\s+'参数适配 current_df = pd.read_csv(csv_path, sep='\s+') # 新增Name列,填入不带后缀的来源文件名 current_df['Name'] = os.path.splitext(os.path.basename(csv_path))[0] df_list.append(current_df) # 合并所有数据并写入目标文件 merged_df = pd.concat(df_list, ignore_index=True) merged_df.to_csv('/opt/home/main.csv', index=False, encoding='utf-8')
该方案的优势:
- 自动对齐不同CSV的列顺序,不会出现手动拼接导致的列错位
- 自动处理重复表头、换行符异常等脏数据问题
- 输出的文件结构完全符合预期,无需手动控制表头写入时机
内容的提问来源于stack exchange,提问作者Tmiskiewicz
相关产品推荐
相关产品推荐

