2012-03-31 10 views
2

テーブルに数値がたくさんあるので、カラムを抽出してmax()を行うことができますが、おそらく、カーネル内の方法を使ってこれを行う方法があります。ちょうど傾けることはそれを見つけるようである。pytablesの "select max(column)from table"と同じもの

答えて

6

を、あなたの代わりにiterrowsメソッドを使用して二回速く結果をオーバー達成することができますof:

In [117]: timeit max(row['timestamp'] for row in table.iterrows(stop=1000000)) 
1 loops, best of 3: 1 s per loop 

In [118]: timeit max(row['timestamp'] for row in table.where('(timestamp<=Tf)')) 
1 loops, best of 3: 2.21 s per loop 

In [120]: timeit max(frames.cols.timestamp[:1000000]) 
1 loops, best of 3: 974 ms per loop 

In [121]: timeit np.max(frames.cols.timestamp[:1000000]) 
1 loops, best of 3: 876 ms per loop 

上記のTfは1000000のエントリですfその列(これはFloat64です)。

質問は比較チェックを要求しないので、どこのテストをスペアすることができますか... 質問で提案された方法(numpy配列としてデータをロードする方法)はまだまだ高速です3%未満で、大きなデータセットの場合はさらに小さくなりますが、10^7行以上はテストしませんでした)。 最高の結果max numpy関数を使用する場所がわかりました(上記参照)。

さらに効率的な方法を学ぶこともできます。

1

High Performance Data Management with PyTables & Family(PDF)から:

e = sum(row['col1'] for row in table.where(3<table.cols.col2<=20)) 

max()使用するためにこれを変更する:私が作ったテストでは

e = max(row['col1'] for row in table.where(3<table.cols.col2<=20)) 
+0

これは動作しますが、これは完全にカーネルではありませんか? where句が大きなセットを返す場合、大きな配列に対してmax()を実行することと等価になります。これはさらに最適化できますか? – jagguli

+0

PyTablesはネイティブで集約関数をサポートしていないようです。 'table.where()'はイテレータを返します。したがって、テーブル全体をメモリに取り込まないでしょう。内部的には、その時点で1つのレコードを読み取り、それを生成します。 "カーネル内"は、 'table.where()'に渡される条件にのみ適用されます。 –

2

私はこれを行うために見つけた最速の方法は、あなたが興味を持っているcolsの上のあなたのテーブルのインデックスを作成することです:インデックス付けたら

table.cols.timestamp.createCSIndex() 

、最大を取得することは、ほぼ瞬時です:

max_timestamp = table.cols.timestamp[table.colindexes['timestamp'][-1]] 

これは、最初にタイムスタンプ列(table.colindexes['timestamp'][-1])のテーブルのIndexオブジェクトから最後の(最大のタイムスタンプに対応する)行インデックスを取得し、対応する列参照にインデックスを付けることによって指す行をフェッチしますtable.cols.timestamp)。

関連する問題