python跳转到txt文件中的一行(一个gzipped)

时间:2015-04-19 23:40:54

标签: python file-io

我正在阅读一个大文件并进行处理。 我希望能够在不花费很长时间的情况下跳到文件的中间。

现在我正在做:

f = gzip.open(input_name)
for i in range(1000000):
    f.read() # just skipping the first 1M rows

for line in f:
    do_something(line)

有没有更快的方法来跳过压缩文件中的行? 如果我必须首先解压缩,我会这样做,但必须有办法。

它当然是一个文本文件,\n分隔行。

4 个答案:

答案 0 :(得分:9)

gzipping的本质是当文件被压缩时不再存在行的概念 - 它只是一个二进制blob。查看this,了解gzip的功能。

要读取文件,您需要对其进行解压缩 - gzip模块可以很好地解决它。与其他答案一样,我也建议itertools进行跳跃,因为它会仔细确保您不会将内容拉入内存,它会尽快让您到达目的地。 / p>

with gzip.open(filename) as f:
    # jumps to `initial_row`
    for line in itertools.slice(f, initial_row, None):
        # have a party

或者,如果这是您正在使用的CSV,您还可以尝试计时pandas解析,因为它可以处理解压缩gzip。这看起来像是:parsed_csv = pd.read_csv(filename, compression='gzip')

另外,要进一步明确,当您在python中迭代文件对象时 - 例如上面的f变量 - 您将遍历行。你不需要考虑' \ n'字符。

答案 1 :(得分:3)

您可以使用itertools.islice,传递文件对象f和起始点,它仍然可以推进迭代器,但比调用下一次1000000次更有效:

from itertools import islice

for line in islice(f,1000000,None):
     print(line)

并不过分熟悉gzip,但我想f.read()读取整个文件,以便接下来的999999次调用无效。如果你想手动推进迭代器,你可以在文件对象上调用next,即next(f)

调用next(f)并不意味着所有行都会立即被读入内存,它会一次使迭代器前进一行,所以如果你想在文件或标题中跳过一行或两行可能很有用。

{@ 3}}食谱作为@wwii建议食谱也值得一试

答案 2 :(得分:1)

不是。

如果您知道要跳过的字节数,可以在文件对象上使用.seek(amount),但为了跳过多行,Python必须逐字节地遍历文件才能计算换行符。

我想到的唯一选择是你处理某个静态文件,这个文件不会改变。在这种情况下,您可以将其编入索引一次,即找出并记住每一行的位置。如果你有这样的话您使用pickle保存并加载的字典,您可以使用seek在准恒定时间内跳过该字典。

答案 3 :(得分:1)

无法在gzip文件中随机搜索。 Gzip是一种流算法,因此必须始终从一开始就解压缩,直到您感兴趣的数据所在。

如果没有索引,则无法跳转到特定行。可以向前扫描行或从文件末尾以连续块的形式向后扫描。

您应该根据需要考虑不同的存储格式。你有什么需求?