【问题标题】:Read Large Gzip Files in Python在 Python 中读取大型 Gzip 文件
【发布时间】:2013-04-26 06:22:23
【问题描述】:

我正在尝试读取一个 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 以外的任何方法)的建议。谢谢。

【问题讨论】:

  • “不可读”是什么意思?
  • 你收到一些错误信息吗?
  • 我遇到内存错误。

标签: python numpy


【解决方案1】:

我的猜测是问题出在您的代码中构造 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

【讨论】:

  • 非常感谢,伙计。我会尝试这些方法并让你们知道。
【解决方案2】:

如果您的问题是内存消耗(您没有包含错误消息...),您可以通过使用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)

【讨论】:

  • 我不确定filter1()...line 只有一行,不是吗?
  • @glglgl,不,get_lines 将其拆分。我将重命名变量以使其更清晰。
  • 非常感谢。我会尝试这些方法并尽快更新你们。
  • 这个也不错..工作得很好。非常感谢,我很感激。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-19
  • 2015-02-03
  • 1970-01-01
  • 2012-10-05
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
相关资源
最近更新 更多