使用大型文本语料库时出现内存错误

时间:2016-12-21 10:32:47

标签: python memory corpus

我有一个大文本文件(~450MB - > 129,000行和457,000,000个字符),当我尝试使用此文件一段时间后,Memory Error上升,这是我的代码:

docDict = {}
ind = 1

with open('somefile.txt',encoding='utf-8') as f:
    for line in f:
        data = line.split(' ')
        docDict[ind] = data
        ind+=1

我看到this,但我逐行阅读文件。

2 个答案:

答案 0 :(得分:1)

为了测试代码中数据结构的开销,我编写了以下测试程序。它假定您的文本文件在ASCII编码中为N兆字节,行相对较短。 (在物理内存耗尽后,我不得不将N从450更改为150。)

import sys

MB = 1024 * 1024

line = "the quick brown fox jumps over the lazy dog"
megs = 150
nlines = (megs * MB) / len(line)

d = {}
for i in xrange(nlines):
    d[i] = line.split(' ')

dict_size = sys.getsizeof(d)
list_size = sum(sys.getsizeof(a) for a in d.items())
item_size = sum(sum(sys.getsizeof(s) for s in a) for a in d.items())

print " dict:", dict_size / float(MB), "MB"
print "lists:", list_size / float(MB), "MB"
print "items:", item_size / float(MB), "MB"
print "total:", (dict_size + list_size + item_size) / float(MB), "MB"

结果:

 dict: 192.00 MB
lists: 251.16 MB
items: 669.77 MB
total: 1112.9 MB

观看Activity Monitor,Python进程超过2 GB的内存使用量,因此还有一些内存没有考虑到。 <{1}}实施的工件可能是可能的。

我在C ++中实现了相同的程序:

malloc

使用#include <string> #include <vector> #include <unordered_map> int main() { int const MB = 1024 * 1024; std::string const line = "the quick brown fox jumps over the lazy dog"; std::vector<std::string> const split = { "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" }; int const megs = 150; int const nlines = (megs * MB) / line.size(); std::unordered_map<int, std::vector<std::string>> d; for (int i = 0; i < nlines; ++i) { d[i] = split; } } 编译,这使用了大约1GB的内存。 C ++没有clang++ -O3因此需要更多的工作来分解内存使用情况,而且我没有这样做。

等效C ++的两倍内存对Python来说实际上是一个非常好的结果,所以我删除了关于cPython实现的预编辑注释。

我认为你的主要问题是将行存储为短字符串数组。您是否可以将行存储为整个字符串并根据需要进行拆分,但不是一次全部拆分?

您的计划的最终目标是什么?

答案 1 :(得分:0)

memory error在这里提升,因为即使您逐行读取文件,也会将其内容存储在字典docDict中,因此也会存储在内存中。

我不知道你打算用这本词典做什么,但我建议你在读完每一行之后再进行这个过程,然后将结果存储在一个变量中(如果进程压缩的话)很多),或直接在文件或数据库中。

希望我帮忙!见啊!