Python 处理巨大的bz2文件

Python 处理巨大的bz2文件,python,csv,sqlite,bzip2,linguistics,Python,Csv,Sqlite,Bzip2,Linguistics,我应该使用python处理一个5+GB的大型bz2文件。对于我的实际代码,我总是得到一个内存错误。在某个地方,我读到我可以使用sqlite3来处理这个问题。是这样吗?如果是,我应该如何调整我的代码? 我对使用sqlite3不是很有经验 以下是代码的实际开头: import csv, bz2 names = ('ID', 'FORM') filename = "huge-file.bz2" with open(filename) as f: f = bz2.BZ2File(f, 'r

我应该使用python处理一个5+GB的大型bz2文件。对于我的实际代码,我总是得到一个内存错误。在某个地方,我读到我可以使用sqlite3来处理这个问题。是这样吗?如果是,我应该如何调整我的代码? 我对使用sqlite3不是很有经验

以下是代码的实际开头:

import csv, bz2

names = ('ID', 'FORM')

filename = "huge-file.bz2"

with open(filename) as f:
    f = bz2.BZ2File(f, 'rb')
    reader = csv.DictReader(f, fieldnames=names, delimiter='\t')
    tokens = [sentence for sentence in reader]

在这之后,我需要检查“代币”。如果我能处理这个巨大的bz2文件就太好了-所以,任何帮助都是非常欢迎的!非常感谢您的建议

文件很大,读取所有文件都不起作用,因为您的进程将耗尽内存

解决方案是以块/行的形式读取文件,并在读取下一个块之前对其进行处理

列表理解行

tokens = [sentence for sentence in reader]
正在将整个文件读取为令牌,这可能会导致进程内存不足

csv.DictReader可以逐行读取csv记录,这意味着在每次迭代中,将有1行数据加载到内存中

像这样:

with open(filename) as f:
    f = bz2.BZ2File(f, 'rb')
    reader = csv.DictReader(f, fieldnames=names, delimiter='\t')
    for sentence in reader:
       # do something with sentence (process/aggregate/store/etc.)
       pass
请注意,如果在添加的循环中,语句中的数据存储在另一个变量(如令牌)中,根据数据的大小,可能会消耗大量内存。因此,最好将它们聚合起来,或者使用其他类型的存储来存储这些数据

使现代化 如评论中所述,关于在流程中使用前面的一些行,您可以执行以下操作:


然后可以将前一行存储在另一个变量中,该变量在每次迭代时都会被替换

或者,如果需要返回多行,则可以列出最后n行

怎样 使用带有maxlen的来跟踪最后n行。从文件顶部的“集合标准”模块导入deque

from collections import deque

# rest of the code ...

last_sentences = deque(maxlen=5) # keep the previous lines as we need for processing new lines
for sentence in reader:
    # process the sentence
    last_sentences.append(sentence)
我建议使用上述解决方案,但您也可以使用列表自行实现,并手动跟踪其大小

在循环之前定义一个空列表,在循环结束时检查列表的长度是否大于所需长度,从列表中删除旧项,然后追加当前行

last_sentences = [] # keep the previous lines as we need for processing new lines
for sentence in reader:
    # process the sentence
    if len(last_sentences) > 5: # make sure we won't keep all the previous sentences
        last_sentences = last_sentences[-5:]
    last_sentences.append(sentence)

非常感谢您的建议!但是直接使用我们的“阅读器”而没有任何列表,是不可能返回一个条目的,是吗?示例:以前,我可以在代币[I-1]['HEAD']时执行此操作dep:i=i-1。这个解决方案是否仍然可行?怎么做?*我只需要后退一步来检查条件,然后你可以将前一行存储在另一个变量中,在每次迭代中都会被替换。因此,总共有2行将保留在内存中,1行用于前一行,1行用于当前行。或者如果你需要多行回复,那么你可以有最后n行的列表。我更新了答案以演示如何跟踪最后几个句子。非常感谢你,法扎德。你的建议和提示帮了大忙!!: