按行中type值将大型CSV文件拆分为多个子CSV文件
按学校类型拆分无序CSV文件的实用方案
针对你遇到的无序大型CSV按学校类型拆分的需求,你找到的基础代码已经能实现单个类型的导出,但我给你优化一下,让它能自动识别所有学校类型并批量生成对应CSV,还能自动处理表头,不用手动复制粘贴,更高效适配大型文件场景。
问题背景回顾
你有一个未排序的CSV文件,表头包含id、type、state、location,数据示例如下:
124,preschool,Pennsylvania,Pittsburgh 421,secondary school,Ohio,Cleveland 213,primary school,California,Los Angeles 155,secondary school,Pennsylvania,Pittsburgh
需要为每种type生成独立的CSV文件且保留表头,之前找到的方案只适用于有序文件或按行数拆分,不符合你的需求。
优化后的批量处理代码
下面是改进后的代码,它会自动遍历所有学校类型,为每个类型创建对应的CSV并自动写入表头和匹配行,而且不会一次性加载整个大文件到内存,适合处理大型数据:
import csv from collections import defaultdict csv_file = 'school.csv' # 用字典存储每个类型对应的文件写入器、表头写入状态和文件句柄 type_writers = defaultdict(lambda: {'writer': None, 'header_written': False, 'file': None}) try: with open(csv_file, 'r', newline='', encoding='utf-8') as csvfile: spamreader = csv.reader(csvfile, delimiter=',') header = next(spamreader) # 先读取表头 for row in spamreader: if not row: # 跳过空行,避免报错 continue school_type = row[1].strip() # 获取当前行的学校类型(去除前后空格) # 如果该类型还没创建文件,就新建并初始化写入器 if not type_writers[school_type]['writer']: output_filename = f'{school_type}.csv' file_handle = open(output_filename, 'w', newline='', encoding='utf-8') writer = csv.writer(file_handle) type_writers[school_type] = { 'writer': writer, 'header_written': False, 'file': file_handle } # 第一次写入时先加表头 if not type_writers[school_type]['header_written']: type_writers[school_type]['writer'].writerow(header) type_writers[school_type]['header_written'] = True # 写入当前行数据 type_writers[school_type]['writer'].writerow(row) finally: # 确保所有打开的文件都被正确关闭,避免资源泄漏 for info in type_writers.values(): if info.get('file'): info['file'].close()
代码亮点
- 自动批量处理:不用手动指定要导出的类型,程序会自动识别CSV里的所有学校类型并生成对应文件
- 自动表头写入:彻底告别手动复制粘贴表头的麻烦,每个导出文件都会自动带上原始表头
- 大文件友好:逐行读取原文件,不会把整个大文件塞进内存,避免内存溢出
- 安全可靠:通过
finally块确保所有文件都被关闭,不会出现文件占用的问题
你的原始代码优化版
如果只需要导出单个特定类型,也可以把你原来的代码调整得更严谨,自动写入表头,还能避免误匹配:
import csv csv_file = 'school.csv' target_type = 'preschool' with open(csv_file, 'r', newline='', encoding='utf-8') as csvfile: spamreader = csv.reader(csvfile, delimiter=',') header = next(spamreader) # 获取表头 with open(f'{target_type}.csv', 'w', newline='', encoding='utf-8') as myfile: spamwriter = csv.writer(myfile) spamwriter.writerow(header) # 先写入表头 for row in spamreader: # 精准匹配第二列的类型,避免其他列包含相同字符串导致误判 if row[1].strip() == target_type: spamwriter.writerow(row)
这样修改后,就不用手动加表头了,而且匹配更准确,不会因为其他列出现preschool字符串就误写入。
内容的提问来源于stack exchange,提问作者monchisan
相关产品推荐
相关产品推荐

