如何使用Python读取处理13GB超大文本文件并解决内存报错问题
问题根因
原代码使用pd.read_csv默认模式会将整个文本文件全量加载到内存,13GB的制表符分隔文本解析为DataFrame后,受类型推断、索引存储、对象类型开销影响,实际内存占用会达到原文件大小的2~3倍,普通消费级设备内存、Colab免费实例内存均无法承载;同时提前将1.5GB RAR包全量解压为13GB TXT文件的操作会占用绝大多数磁盘空间,后续再写入CSV文件时会直接耗尽存储空间导致崩溃。
处理方案
全程采用流式读取+分块处理逻辑,既不需要把压缩包内的TXT全量解压到磁盘,也不会把全量数据加载到内存,从根源解决内存、磁盘空间不足的问题。
- 前置依赖安装
执行命令安装需要的依赖库:pip install rarfile pandas
Colab/Linux环境额外执行系统命令安装rar解压依赖:apt install -y unrar;Windows环境可将7-Zip的可执行文件路径加入系统环境变量供rarfile调用。 - 方案1:Pandas分块读写(适配需要用Pandas做简单数据处理的场景)
直接读取压缩包内的文件流,按固定行数分块解析、逐块写入目标CSV,内存占用仅和单块大小相关,设置10万行/块时内存占用通常不超过1GB,磁盘仅需存储原RAR包和最终CSV文件,不需要保留中间解压的TXT文件。import rarfile import pandas as pd # 配置项根据实际路径修改 RAR_FILE_PATH = "你的压缩包存储路径/文件名.rar" TXT_NAME_IN_RAR = "压缩包内的目标txt文件名.txt" OUTPUT_CSV_PATH = "CSV输出路径/最终文件名.csv" CHUNK_ROW_SIZE = 100000 # 单块处理行数,内存不足可适当调小 with rarfile.RarFile(RAR_FILE_PATH) as rf: # 直接打开压缩包内的文件为字节流,不落地解压 with rf.open(TXT_NAME_IN_RAR) as txt_stream: write_header = True # 分块迭代读取 for chunk in pd.read_csv(txt_stream, sep="\t", chunksize=CHUNK_ROW_SIZE): chunk.to_csv( OUTPUT_CSV_PATH, mode="w" if write_header else "a", index=False, header=write_header ) write_header = False - 方案2:原生CSV模块流式处理(适配仅做格式转换、追求更高速度更低占用的场景)
跳过Pandas的DataFrame解析开销,直接用Python标准库的csv模块做逐行批量读写,速度比Pandas方案快30%以上,内存占用可低至300MB以内。import rarfile import csv RAR_FILE_PATH = "你的压缩包存储路径/文件名.rar" TXT_NAME_IN_RAR = "压缩包内的目标txt文件名.txt" OUTPUT_CSV_PATH = "CSV输出路径/最终文件名.csv" BATCH_ROW_SIZE = 50000 with rarfile.RarFile(RAR_FILE_PATH) as rf: with rf.open(TXT_NAME_IN_RAR) as in_stream, open(OUTPUT_CSV_PATH, "w", newline="", encoding="utf-8") as out_stream: tsv_reader = csv.reader(in_stream, delimiter="\t") csv_writer = csv.writer(out_stream, delimiter=",") row_batch = [] for row in tsv_reader: row_batch.append(row) if len(row_batch) >= BATCH_ROW_SIZE: csv_writer.writerows(row_batch) row_batch.clear() # 写入最后不足批量大小的剩余行 if row_batch: csv_writer.writerows(row_batch)
额外优化建议
如果你的最终目标不是单纯生成CSV文件,而是要做数据筛选、统计、清洗,可以直接在分块循环内对每一块数据做处理,不需要落地存储全量CSV文件,能进一步节省磁盘空间:
- 做数据筛选:每块过滤掉不符合条件的行后,只保留需要的结果
- 做聚合统计:每块先计算局部聚合结果,所有块处理完成后再合并局部结果得到全局统计值,不需要加载全量数据
内容的提问来源于stack exchange,提问作者Ghost
相关产品推荐
相关产品推荐

