正在加载/流式传输8GB txt文件?然后标记化

时间:2019-07-17 19:52:57

标签: python nltk file-read

我有一个很大的文件(大约8 GB)。.现在我读这篇文章:How to read a large file line by line和这个Tokenizing large (>70MB) TXT file using Python NLTK. Concatenation & write data to stream errors

但这仍然不能完成工作。.当我运行代码时,我的电脑卡住了。 我在做错什么吗?

我想将所有单词都放入列表中(对它们进行标记)。此外,代码不读取每一行并标记该行吗?因为某些单词(和句子)并没有在一行之后才结束,这是否可能会阻止分词器正确地分词?

我曾考虑将其拆分为较小的文件,但是如果我只有8GB Ram,这是否仍会占用我的RAM,因为单词列表可能与初始txt文件一样大(8GB)?

word_list=[]
number = 0
with open(os.path.join(save_path, 'alldata.txt'), 'rb',encoding="utf-8") as t:
    for line in t.readlines():
        word_list+=nltk.word_tokenize(line)
        number = number + 1
        print(number)

1 个答案:

答案 0 :(得分:2)

使用以下行:

for line in t.readlines():
    # do the things

您正在强迫python使用t.readlines()读取整个文件,然后返回代表整个文件的字符串数组,从而将整个文件带入内存。

相反,如果您以示例为例,则链接状态:

for line in t:
    # do the things

Python VM将按需本机逐行处理文件。 该文件将像generator一样工作,一次生成每一行。


再次查看您的代码后,我发现您不断使用word_list += nltk.word_tokenize(line)附加到单词列表。这意味着即使您确实一次导入了一行文件,即使文件继续移动,您仍将这些数据保留在内存中。您可能需要找到一种更好的方法来执行此操作,因为您仍将消耗大量内存,因为尚未从内存中删除数据。


对于如此大的数据,您将必须

  • 找到一种存储令牌化数据的中间版本的方法,或者
  • 设计代码的方式可以同时处理一个或几个标记化的单词。

类似这样的事情可能会解决问题:

def enumerated_tokens(filepath):
    index = 0
    with open(filepath, rb, encoding="utf-8") as t:
        for line in t:
            for word in nltk.word_tokenize(line):
                yield (index, word)
                index += 1

for index, word in enumerated_tokens(os.path.join(save_path, 'alldata.txt')):
    print(index, word)
    # Do the thing with your word.

请注意,这实际上不会在任何地方存储单词。这并不意味着您不能暂时存储任何内容,但是如果您的内存有限,则可以使用生成器。这种方法可能会更快,更稳定并且总体上使用更少的内存。