Python使用with open过滤大型CSV失效,如何生成筛选后新文件或pandas DataFrame?
大体积CSV文件按规则过滤的问题排查与实现方案
原代码失效的核心原因
- 逻辑绑定错误:
outfile.write(lines)的代码位置与if判断同级,不属于if的内部执行块,程序每读取一行不管是否匹配31/10/2018的筛选规则,都会无条件执行写入操作,这就是输出文件与原文件内容、大小完全一致的根本原因。 - 文件打开模式不合理:输出文件使用追加模式
'a'打开,重复运行代码会不断在原有文件尾部重复追加内容,容易造成数据混乱。 - 资源管理不规范:输出文件没有使用上下文管理器(
with语法),遇到程序中断时容易出现内容未正常刷盘、文件句柄泄漏的问题。
可直接运行的修正实现
方案1:逐行流式读写(适配GB/ TB级超大CSV,内存占用极低)
这种方法不需要把整个文件加载到内存,适合体积超出内存容量的大文件,代码如下:
# 同时用上下文管理器管理输入、输出文件,自动处理文件关闭/刷盘逻辑 # 输出文件使用写模式'w',避免追加造成的内容重复 with open('my_file1.csv', 'r', encoding='utf-8') as in_f, \ open('my_file2.csv', 'w', encoding='utf-8') as out_f: # 如果需要保留CSV表头,可在此处先读取第一行写入输出文件 # out_f.write(in_f.readline()) for line in in_f: # 只有匹配筛选条件的行,才会执行打印和写入操作 if '31/10/2018' in line: print(line) out_f.write(line)
注意:如果CSV有固定表头,记得在循环逐行处理前先把表头行写入输出文件,避免生成的过滤文件缺少列名。
方案2:pandas实现(适配需要后续数据分析的场景)
如果文件体积可被内存承载,或是需要直接得到可分析的DataFrame结果,可使用pandas的分块读取功能实现过滤,避免一次性加载大文件造成内存溢出:
import pandas as pd filtered_data = [] # 分块读取大文件,可根据实际内存调整单块行数 for chunk in pd.read_csv('my_file1.csv', chunksize=100000): # 筛选包含目标日期的行,追加到结果列表 matched_chunk = chunk[chunk.apply( lambda row: '31/10/2018' in str(row.values), axis=1 )] filtered_data.append(matched_chunk) # 合并所有匹配的分块,得到最终的DataFrame result_df = pd.concat(filtered_data, ignore_index=True) # 可选:将筛选结果另存为新的CSV文件 result_df.to_csv('my_file2.csv', index=False, encoding='utf-8-sig')
内容的提问来源于stack exchange,提问作者Domec
相关产品推荐
相关产品推荐

