加载/流式传输 8GB txt 文件??并标记化
Loading / Streaming 8GB txt file?? And tokenize
我有一个相当大的文件(大约 8 GB)..现在我读到这个 post:How to read a large file line by line and this one 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)
通过使用以下行:
for line in t.readlines():
# do the things
您强制 python 使用 t.readlines()
读取整个文件,然后 return 表示整个文件的字符串数组,从而将整个文件放入内存。
相反,如果您按照链接状态的示例进行操作:
for line in t:
# do the things
Python VM 将按照您的意愿在本机处理文件 line-by-line。
该文件将像 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.
请注意,这实际上从未将单词存储在任何地方。这并不意味着你不能临时存储任何东西,但如果你的内存有限,生成器是可行的方法。这种方法可能会更快、更稳定,并且总体上使用更少的内存。
我有一个相当大的文件(大约 8 GB)..现在我读到这个 post:How to read a large file line by line and this one 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)
通过使用以下行:
for line in t.readlines():
# do the things
您强制 python 使用 t.readlines()
读取整个文件,然后 return 表示整个文件的字符串数组,从而将整个文件放入内存。
相反,如果您按照链接状态的示例进行操作:
for line in t:
# do the things
Python VM 将按照您的意愿在本机处理文件 line-by-line。 该文件将像 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.
请注意,这实际上从未将单词存储在任何地方。这并不意味着你不能临时存储任何东西,但如果你的内存有限,生成器是可行的方法。这种方法可能会更快、更稳定,并且总体上使用更少的内存。