2011-08-16 4 views
8

大きなファイル(1億行のタブ区切り値 - 約1.5GBのサイズ)があります。フィールドの1つに基づいてこれを並べ替える最も速い方法は何ですか?大きなテキストデータをソートする

私はハイブを試しました。私はこれがPythonを使ってより速くできるかどうかを見たいと思います。

答えて

16

* nix sortプログラムを使用したことがありますか?基本的には、ほとんどのPythonスクリプトより速いでしょう。

使用-t $'\t'それはあなたが出力に新しいファイルに結果をしたい場合nはフィールド番号であるフィールド、および-o outputfileを指定するには、タブ区切り、-k nだことを指定します。 例:

sort -t $'\t' -k 4 -o sorted.txt input.txt 

は、あなたが、その後に興味があり、フィールドにインデックスそれを、私は良いリレーショナルデータベースにファイルを格納しますsorted.txt

+0

unix sortコマンドは確かに非常に強力なツールです。並べ替えるフィールドの形式(数値、日付など)と、プログラムが割り当てることができるメモリの量を制御し、必要に応じて分割+マージソートを実行できます。 –

+0

アレックスの例がありますか?ソートプログラム自体はかなり長い時間がかかります... 40分程度です。これはメモリ割り当てやディスクIOと関係があります。私はボトルネックが何であるか把握する方法はわかりませんが、あなたの提案が役に立つかもしれないと推測しています。 – fodon

+1

上記の解決策に1つのエラーがあります:第2フィールドのみを使用するには、1つは-k 2,2 ...が必要です。したがって、インデックスはゼロになりません(少なくともKubuntu 11.04のソートバージョンではありません)。 – fodon

1

に結果をその第四フィールド上input.txtを並べ替え、および出力ウィル注文したアイテムを読んでください。あなたは、ファイルのために、メモリ内のインデックスを構築したい

7

  1. f.readline()を使用して行(、リスト内の店舗でそれをラインを読ん
  2. openにファイルを空のリストを作成します並べ替えたい値(line.split('\t').strip()で抽出)とファイル内の行のオフセット(f.readline()を呼び出す前にf.tell()を呼び出して取得できる)からなるタプル
  3. closeファイル
  4. 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) 
3

はメモリーでソート可能なファイルに分割。メモリ内の各ファイルをソートします。次に、結果のファイルをマージします。

マージする各ファイルの一部を読み取ってマージします。マージされた結果のメモリに十分なスペースを残して、各ファイルから同じ量。これを保存すると一旦マージされます。結合されたデータのブロックをファイルに追加することを繰り返します。

これは、ファイルの入出力を最小化し、ディスク上のファイルを移動することを最小限に抑えます。

関連する問題