我有一个非常大的4+ GB大小的文本文件,我有一个脚本,根据第一个昏迷之前的字符将文件拆分为小文件。例如:16,....行转到16.csv,61,....行转到61.csv.不幸的是,这个脚本运行了很长时间,我猜是因为写出方法的原因。有什么方法可以加速脚本吗?
import pandas as pd
import csv
with open (r"updates//merged_lst.csv",encoding="utf8", errors='ignore') as f:
r = f.readlines()
for i in range(len(r)):
row = r[i]
letter = r[i].split(',')[0]
filename = r"import//"+letter.upper()+".csv"
with open(filename,'a',encoding="utf8", errors='ignore') as f:
f.write(row)
4条答案
按热度按时间osh3o9ms1#
我不确定这是否真的有很大的不同,或者瓶颈是否在其他地方,但我不会为输入中的每一行打开和关闭输出文件,而是将每个输出文件打开一次并重用它。
为了同时打开多个文件并使用正确的文件进行写入,我会将它们放入字典中,使用
letter
作为键:(除了检查
if letter not in files
,您还可以使用files.setdefault
。)你必须在最后关闭它们以确保内容被写入磁盘。或者在循环中手动执行此操作:
或者您仍然可以使用上下文管理器(
with
语句),请参见JonSG's answer。4sup72z82#
17个打开的文件看起来并不是太多以至于无法管理。我会尝试通过
contextlib.ExitStack()
构建上下文字典。这将允许您有一个干净和可管理的方式来保持输出文件打开,这样您就不会不断地重新打开它们,因为这可能会使事情变慢,或者至少没有帮助。注意:我简化了你的文件名只是为了让事情看起来更容易,所以如果你尝试这样做,你会想修复它。
如果你想把字典限制在输出文件中,你甚至可以这样做:
hjqgdpho3#
下面是您的原始代码、mkrieger1、我的贡献和iohans的Pandas解决方案的一些性能比较,因为:Don't use Pandas to iterate rows.
要对这些进行基准测试:
1.我生成了三个示例输入CSV文件,每个文件看起来如下所示:
两列都是从1到10的随机整数。三个示例CSV的行大小会增长:
1.我用了你的密码,mkrieger1的,还有我的:
以下是结果:
| 版本|大小|真实值(s)|用户|系统|内存(MB)|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 版本1||||||
| | 10e5|四点零四分|0.44|一点八三|十二时十九分|
| | 10e6|二十三块九七|四点二九|十七点七九分|八十一点四九分|
| | 10e7|二一四点七四|四十三点五四分|一百六十七点三五|小行星702.08|
| 版本2||||||
| | 10e5|0.03分|0.02分|0.0分|十二时十九分|
| | 10e6|0.2分|0.18|0.01分|八十一点九一分|
| | 10e7|一点八二|1.7岁|0.11|小行星702.91|
| 版本3||||||
| | 10e5|0.03分|0.03分|0.0分|七点四十七分|
| | 10e6|0.23|0.22|0.0分|七点七七|
| | 10e7|二、三|二点二七分|0.03分|八点五六分|
| 版本4||||||
| | 10e5|十二点五|十一时零五分|三点二八分|五十四点八五分|
| | 10e6|一百二十一点八九|九十九点二|二十四点五四分|八十块八一|
| | 10e7|1020人以上|不适用|不适用|不适用|
我们如何使内存使用接近于零?
正如一些评论所建议的,通过增量读取输入并决定在读取时对每行执行什么操作:
我也使用csv模块,因为它可以正确处理CSV格式。如果你知道100%,你的CSV文件没有嵌入换行符,如:
那么你可以一行一行地读/写,然后在你看到的第一个逗号上拆分,但是,即使你知道这一点,无论如何,仅仅使用csv模块也不会有太多的时间损失。
btqmn9zl4#
阅读文件的节并使用
to_csv
可以加快这个脚本的速度。这个例子一次读取500,000行的大文件。