【发布时间】:2017-11-08 19:39:33
【问题描述】:
我需要扫描两个大的txt文件(都大约100GB,10亿行,几列)并取出某一列(写入新文件)。文件如下所示
ID*DATE*provider
1111*201101*1234
1234*201402*5678
3214*201003*9012
...
我的 Python 脚本是
N100 = 10000000 ## 1% of 1 billion rows
with open("myFile.txt") as f:
with open("myFile_c2.txt", "a") as f2:
perc = 0
for ind, line in enumerate(f): ## <== MemoryError
c0, c1, c2 = line.split("*")
f2.write(c2+"\n")
if ind%N100 == 0:
print(perc, "%")
perc+=1
现在上面的脚本在一个文件上运行良好,但在另一个文件上却卡在了 62%。错误消息为for ind, line in enumerate(f): 显示MemoryError。我在不同RAM的不同服务器上尝试了几次,错误是一样的,都是62%。我等了几个小时来监控 RAM,当 62% 时它爆炸到 28GB(总计 = 32GB)。所以我猜在那个文件中有一行太长了(可能没有以\n 结尾?),因此 Python 在尝试将其读取到 RAM 时卡住了。
所以我的问题是,在我去我的数据提供者之前,我能做些什么来检测错误行并以某种方式绕过/跳过将其作为一条大线读取?感谢任何建议!
编辑:
从“错误行”开始的文件可能与另一个行分隔符而不是\n 混淆在一起。如果是这种情况,我可以检测到 sep 行并继续提取我想要的列,而不是扔掉它们吗?谢谢!
【问题讨论】:
-
如果你监控前62%的进程,内存使用是否稳定增长?您可能有与行解析无关的内存泄漏。
-
您可以在文件对象上使用
readline方法,该方法接受最大行长度。 -
其实没有。在接近 62% 之前一切都很好
-
然后放弃“逐行”方法,逐个字符读取,计算“*”和换行符。
-
@Jean-FrançoisFabre 或一些合理的“块”。
标签: python out-of-memory bigdata