2016-09-26 1 views
1

テーブル内の特定の条件に一致する行(数十億行)のインデックスが必要です私は現在動作しますが、非常に醜いです私のコードで使用ラインは:`Table.where() 'を使用して条件に一致するPyTablesテーブルの行のインデックスを取得します。

indices = np.array([row.nrow for row in the_table.where("foo == 42")]) 

はまた半分分かかり、そして私は、リストの作成が理由の一つであることを確信しています。

私はまだエレガントな解決策を見つけることができませんでしたが、私はまだpytablesのドキュメントに苦しんでいます。だから、もっと美しくやや速くするための魔法の方法は誰にも分かりますか?おそらく、私はpytablesがnumpyの配列として一致する行のインデックスを返すことができるはずだという気持ちがあるので、私は行方不明の特別なクエリキーワードがあります。

+0

* *「私は、リストの作成が理由の一つであることを確信している」 - あなたはそれがちょうど一致する行を反復するために要する時間をベンチマークしていますリストや配列を作成することなく?リストの作成がここでボトルネックになっていると私は驚いています。 –

+0

コメントありがとうございます!はい、私はそれをベンチマークしており、テストファイルの場合は約14秒(リストの理解のみ)対27秒(リストの理解+ 'numpy.array')なので、計算時間の50%は' numpy.array'の作成です。 – tamasgal

+0

'indices'の典型的なサイズはどれくらいですか?どのくらいのRAMがありますか? –

答えて

0

私はpytablesのソースを読んでいますが、where()はCythonで実装されていますが、それほど高速ではないようです。

は最初のいくつかのデータを作成します:

from tables import * 
import numpy as np 

class Particle(IsDescription): 
    name  = StringCol(16) # 16-character String 
    idnumber = Int64Col()  # Signed 64-bit integer 
    ADCcount = UInt16Col()  # Unsigned short integer 
    TDCcount = UInt8Col()  # unsigned byte 
    grid_i = Int32Col()  # 32-bit integer 
    grid_j = Int32Col()  # 32-bit integer 
    pressure = Float32Col() # float (single-precision) 
    energy = Float64Col() # double (double-precision) 
h5file = open_file("tutorial1.h5", mode = "w", title = "Test file") 
group = h5file.create_group("/", 'detector', 'Detector information') 
table = h5file.create_table(group, 'readout', Particle, "Readout example") 
particle = table.row 
for i in range(1001000): 
    particle['name'] = 'Particle: %6d' % (i) 
    particle['TDCcount'] = i % 256 
    particle['ADCcount'] = (i * 256) % (1 << 16) 
    particle['grid_i'] = i 
    particle['grid_j'] = 10 - i 
    particle['pressure'] = float(i*i) 
    particle['energy'] = float(particle['pressure'] ** 4) 
    particle['idnumber'] = i * (2 ** 34) 
    # Insert a new particle record 
    particle.append() 

table.flush() 
h5file.close() 

をチャンクで列を読み込み、リストにインデックスを追加し、最終的に配列にリストを連結ここでスピードアップすることができ、複雑な方法があります。あなたは、メモリのサイズに応じてチャンクサイズを変更することができます。

h5file = open_file("tutorial1.h5") 

table = h5file.get_node("/detector/readout") 

size = 10000 
col = "energy" 
buf = np.zeros(batch, dtype=table.coldtypes[col]) 
res = [] 
for start in range(0, table.nrows, size): 
    length = min(size, table.nrows - start) 
    data = table.read(start, start + batch, field=col, out=buf[:length]) 
    tmp = np.where(data > 10000)[0] 
    tmp += start 
    res.append(tmp) 
res = np.concatenate(res) 
関連する問題