0

HDF5 に保存し、PyTables を使用してアクセスするかなり大きなデータセットがあります。このデータセットに対して実行する必要がある操作の 1 つは、各要素間のペアごとの比較です。これには 2 つのループが必要です。1 つは各要素を反復するループで、内側のループは他のすべての要素を反復するループです。したがって、この操作では N(N-1)/2 の比較が行われます。

かなり小さいセットの場合、内容を多次元のnumpy配列にダンプしてから反復を行う方が高速であることがわかりました。メモリの問題が原因で大規模なセットで問題が発生し、実行時にデータセットの各要素にアクセスする必要があります。

要素を配列に入れると、1 秒あたり約 600 回の比較が行われますが、hdf5 データ自体を操作すると、1 秒あたり約 300 回の比較が行われます。

このプロセスをスピードアップする方法はありますか?

例は次のとおりです(これは私の実際のコードではなく、単なる例です):

スモールセット

with tb.openFile(h5_file, 'r') as f:
    data = f.root.data

    N_elements = len(data)
    elements = np.empty((N_elements, 1e5))

    for ii, d in enumerate(data):
        elements[ii] = data['element']

D = np.empty((N_elements, N_elements))  
for ii in xrange(N_elements):
    for jj in xrange(ii+1, N_elements):             
        D[ii, jj] = compare(elements[ii], elements[jj])

大型セット:

with tb.openFile(h5_file, 'r') as f:
    data = f.root.data

    N_elements = len(data)        

    D = np.empty((N_elements, N_elements))  
    for ii in xrange(N_elements):
        for jj in xrange(ii+1, N_elements):             
             D[ii, jj] = compare(data['element'][ii], data['element'][jj])
4

1 に答える 1

0

ここで提案する2つのアプローチ:

  1. numpy memmap: メモリ マップド配列を作成し、この中にデータを配置してから、"Small Set" のコードを実行します。メモリ マップは、ほとんど配列のように動作します。

  2. multiprocessing-module を使用して並列処理を許可します。「compare」メソッドが少なくともかなりの量の CPU 時間を消費する場合は、複数のプロセスを使用できます。

CPU に複数のコアがあると仮定すると、これは大幅に高速化されます。使用する

  • hdf からデータを読み取り、キューに入れる 1 つのプロセス
  • キューから取得して比較を行い、結果を「出力キュー」に入れる1つのプロセス
  • 結果を再度収集するための 1 つのプロセス。

方法を選択する前に: 「敵を知る」、つまりプロファイリングを使用してください! 最適化は、ボトルネックを改善する場合にのみ努力する価値があるため、最初に貴重な CPU 時間を消費する方法を見つけてください。

あなたのアルゴリズムは O(n^2) で、大きなデータには適していません。ロジックを適用するなどして、これを減らす方法はありませんか? これは常に最良のアプローチです。

ご挨拶、

トルステン

于 2013-01-03T15:28:37.563 に答える