ファイルを完全に抽出せずに、Pythonを使用してgz圧縮されたテキストファイルから行を読み取るのは簡単ですか?私は約200mbのtext.gzファイルを持っています。抽出すると7.4GBになります。そして、これは私が読まなければならない唯一のファイルではありません。全体のプロセスでは、10個のファイルを読み取る必要があります。これはシーケンシャルな仕事ですが、情報全体を抽出せずに行うのは賢明なことだと思います。それが可能かどうかさえ知りません。Pythonを使用してどのように行うことができますか?テキストファイルを1行ずつ読む必要があります。
4 に答える
import gzip
with gzip.open('input.gz','rt') as f:
for line in f:
print('got line', line)
注:gzip.open(filename, mode)
はのエイリアスですgzip.GzipFile(filename, mode)
。with open(...) as f:
圧縮されていないファイルを開くために使用されるのと似ているので、前者の方が好きです。
Pythonで標準のgzipモジュールを使用できます。使用するだけです:
gzip.open('myfile.gz')
他のファイルと同じようにファイルを開き、その行を読み取ります。
詳細はこちら:Pythongzipモジュール
gzip.GzipFileを使用してみましたか?引数はに似ていopen
ます。
gzipライブラリは(明らかに)を使用しますgzip
が、これは少し遅くなる可能性があります。の並列化バージョンであるpigzへのシステムコールを使用すると、処理を高速化できますgzip
。欠点は、インストールする必要がありpigz
、実行中に多くのコアが必要になることですが、はるかに高速で、メモリを大量に消費しません。その場合、ファイルの呼び出しはのos.popen('pigz -dc ' + filename)
代わりになりますgzip.open(filename,'rt')
。pigzフラグは-d
、解凍用および-c
stdout出力用であり、.によって取得できますos.popen
。
次のコードは、ファイルと数値(1または2)を取り込んで、コードにかかる時間を測定しながら、さまざまな呼び出しでファイル内の行数をカウントします。で次のコードを定義しますunzip-file.py
:
#!/usr/bin/python
import os
import sys
import time
import gzip
def local_unzip(obj):
t0 = time.time()
count = 0
with obj as f:
for line in f:
count += 1
print(time.time() - t0, count)
r = sys.argv[1]
if sys.argv[2] == "1":
local_unzip(gzip.open(r,'rt'))
else:
local_unzip(os.popen('pigz -dc ' + r))
/usr/bin/time -f %M
28Gファイルでプロセスの最大メモリ使用量を測定するを使用してこれらを呼び出すと、次のようになります。
$ /usr/bin/time -f %M ./unzip-file.py $file 1
(3037.2604110240936, 1223422024)
5116
$ /usr/bin/time -f %M ./unzip-file.py $file 2
(598.771901845932, 1223422024)
4996
基本的に同じ最大メモリを使用すると、システムコールが約5倍高速(50分に対して10分)であることを示しています。また、ファイルの1行あたりの読み取りを行うことによっては、制限要因にならない場合があることにも注意してください。その場合、選択するオプションは重要ではありません。