Python 跳转到 TXT 文件中的一行(一个 gzip 文件)



我正在读取一个大文件,并对其进行处理。我希望能够跳到文件的中间,而不会花费很长时间。

现在我正在做:

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分隔线。

gzipping 的本质是,当文件被压缩时,不再有行的概念——它只是一个二进制 blob。查看此内容以了解gzip的功能。

要读取文件,您需要解压缩它 - gzip模块做得很好。像其他答案一样,我也建议itertools进行跳跃,因为它会小心翼翼地确保你不会把东西拉到记忆中,它会尽快让你到达那里。

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变量 - 你迭代了行。您无需考虑""字符。

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

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

不太熟悉 gzip,但我想f.read()会读取整个文件,因此接下来的999999调用什么都不做。如果你想手动推进迭代器,你将在文件对象上调用下一个,即next(f)

调用next(f)并不意味着所有行都一次读入内存,它会一次推进一行迭代器,因此如果您想跳过文件或标头中的一两行,它会很有用。

作为建议食谱@wwii消费食谱也值得一试

不是真的。

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

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

不可能

在 gzip 文件中随机查找。Gzip 是一种流算法,因此它必须始终从头开始解压缩,直到您感兴趣的数据所在的位置。

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

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

最新更新