繁体   English   中英

在Python中读取大型Gzip文件

[英]Read Large Gzip Files in Python

我正在尝试读取gzip文件(大小约为150 MB)并使用此脚本(我知道写得不好):

import gzip

f_name = 'file.gz'

a = []

with gzip.open(f_name, 'r') as infile:
    for line in infile:
        a.append(line.split(' '))

new_array1 = []

for l in a:
    for i in l:
        if i.startswith('/bin/movie/tribune'):
            new_array1.append(l)

filtered = []

for q in range(0, len(new_array1)):
    filtered.append(new_array1[q])

#at this point filtered array can be printed

问题是,我可以使用此技术将最多50 MB的文件读入数组,但是80 MB及以上的文件大小不可读。 我正在使用的技术是否存在问题或存在内存限制? 如果是第二种情况,那么以python数组读取大型gz文件(大于100 MB)的最佳技术应该是什么? 任何帮助将不胜感激。

注意:我没有使用NumPy,因为我遇到了服务器上C编译器的一些严重问题,这对于numpy是必需的,因此我无法使用它。 因此,请提出一些使用本机Pythonic方法(或NumPy以外的方法)的建议。 谢谢。

我的猜测是问题a在代码中,因为如果.gz这么大,那无疑将包含大量条目。 此修改应解决该问题:

import gzip

f_name = 'file.gz'

filtered = []
with gzip.open(f_name, 'r') as infile:
    for line in infile:
        for i in line.split(' '):
            if i.startswith('/bin/movie/tribune'):
                filtered.append(line)
                break # to avoid duplicates

如果您的问题是内存消耗(您未包括错误消息...),则可以通过使用generators避免存储临时列表,从而节省大量内存。

例如

import gzip
f_name = 'file.gz'

def get_lines(infile):
    for line in infile:
        yield line.split()

def filter1(line_tokens):
    return any( token.startswith('/bin/movie/tribune')  for token in line_tokens )

def filter2(line_tokens):
    # was there a filter2?
    return True

infile = gzip.open(f_name, 'r')

filtered = ( line_tokens for line_tokens in get_lines(infile) if filter1(line_tokens) and filter2(line_tokens) )

for line in filtered:
    print line

在我的示例中filter2是微不足道的,因为看来您的filtered列表只是new_array1的(未过滤)副本...

这样,您可以避免将整个内容存储在内存中。 请注意,由于filtered是生成器,因此只能对其进行迭代一次。 如果确实需要完全存储它,请执行filtered = list(filtered)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM