我正在读取一个大文件,并对其进行处理。我希望能够跳到文件的中间,而不会花费很长时间。
现在我正在做:
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 是一种流算法,因此它必须始终从头开始解压缩,直到您感兴趣的数据所在的位置。
如果没有索引,则无法跳转到特定行。行可以在连续块中从文件末尾向前扫描或向后扫描。
您应该考虑根据需要使用不同的存储格式。您的需求是什么?