大きなファイル(1億行のタブ区切り値 - 約1.5GBのサイズ)があります。フィールドの1つに基づいてこれを並べ替える最も速い方法は何ですか?大きなテキストデータをソートする
私はハイブを試しました。私はこれがPythonを使ってより速くできるかどうかを見たいと思います。
大きなファイル(1億行のタブ区切り値 - 約1.5GBのサイズ)があります。フィールドの1つに基づいてこれを並べ替える最も速い方法は何ですか?大きなテキストデータをソートする
私はハイブを試しました。私はこれがPythonを使ってより速くできるかどうかを見たいと思います。
* nix sort
プログラムを使用したことがありますか?基本的には、ほとんどのPythonスクリプトより速いでしょう。
使用-t $'\t'
それはあなたが出力に新しいファイルに結果をしたい場合n
はフィールド番号であるフィールド、および-o outputfile
を指定するには、タブ区切り、-k n
だことを指定します。 例:
sort -t $'\t' -k 4 -o sorted.txt input.txt
は、あなたが、その後に興味があり、フィールドにインデックスそれを、私は良いリレーショナルデータベースにファイルを格納しますsorted.txt
に結果をその第四フィールド上input.txt
を並べ替え、および出力ウィル注文したアイテムを読んでください。あなたは、ファイルのために、メモリ内のインデックスを構築したい
:
f.readline()
を使用して行(、リスト内の店舗でそれをラインを読んopen
にファイルを空のリストを作成します並べ替えたい値(line.split('\t').strip()
で抽出)とファイル内の行のオフセット(f.readline()
を呼び出す前にf.tell()
を呼び出して取得できる)からなるタプルclose
ファイルsort
リスト次に読むために、ソートされたファイルを印刷し、ファイルを再度開くと、あなたのリストの各要素について、行の先頭にファイルポインタを移動するためにf.seek(offset)
を使用し、f.readline()
します線とprint
線。
最適化:印刷フェーズでf.read(length)
を使用できるように、リストの行の長さをリストに保存することができます。 (読みやすさではなく、速度を最適化)
サンプルコード:
def build_index(filename, sort_col):
index = []
f = open(filename)
while True:
offset = f.tell()
line = f.readline()
if not line:
break
length = len(line)
col = line.split('\t')[sort_col].strip()
index.append((col, offset, length))
f.close()
index.sort()
return index
def print_sorted(filename, col_sort):
index = build_index(filename, col_sort)
f = open(filename)
for col, offset, length in index:
f.seek(offset)
print f.read(length).rstrip('\n')
if __name__ == '__main__':
filename = 'somefile.txt'
sort_col = 2
print_sorted(filename, sort_col)
はメモリーでソート可能なファイルに分割。メモリ内の各ファイルをソートします。次に、結果のファイルをマージします。
マージする各ファイルの一部を読み取ってマージします。マージされた結果のメモリに十分なスペースを残して、各ファイルから同じ量。これを保存すると一旦マージされます。結合されたデータのブロックをファイルに追加することを繰り返します。
これは、ファイルの入出力を最小化し、ディスク上のファイルを移動することを最小限に抑えます。
unix sortコマンドは確かに非常に強力なツールです。並べ替えるフィールドの形式(数値、日付など)と、プログラムが割り当てることができるメモリの量を制御し、必要に応じて分割+マージソートを実行できます。 –
アレックスの例がありますか?ソートプログラム自体はかなり長い時間がかかります... 40分程度です。これはメモリ割り当てやディスクIOと関係があります。私はボトルネックが何であるか把握する方法はわかりませんが、あなたの提案が役に立つかもしれないと推測しています。 – fodon
上記の解決策に1つのエラーがあります:第2フィールドのみを使用するには、1つは-k 2,2 ...が必要です。したがって、インデックスはゼロになりません(少なくともKubuntu 11.04のソートバージョンではありません)。 – fodon