2017-01-09 11 views
2

HDF5データベースからの特定の時間間隔の時系列データについて連続してたくさんのクエリを実行する必要があります(データは常にストートではなく、常に「連続」ではありません)。開始時刻と終了時刻)。任意のコメントや提案Python - Fast HDF5時系列データのクエリ

import pandas as pd 
from pandas import HDFStore 

store = HDFStore(pathToStore) 
dates = pd.date_range(start=start_date,end=end_date, freq='S') 
index = store.select_column('XAU','index') 
ts = store.select('XAU', where=index[index.isin(dates)].index) 

が高く評価され、THX:this answerに触発された私の現在のコード、より速く解決策がある天気をので、私は疑問に思います!

答えて

3

それを試してみましょう!

生成1M行DF:

In [129]: df = pd.DataFrame({'val':np.random.rand(10**6)}, index=pd.date_range('1980-01-01', freq='19S', periods=10**6)) 

In [130]: df.shape 
Out[130]: (1000000, 1) 

In [131]: df.head() 
Out[131]: 
          val 
1980-01-01 00:00:00 0.388980 
1980-01-01 00:00:19 0.916917 
1980-01-01 00:00:38 0.894360 
1980-01-01 00:00:57 0.235797 
1980-01-01 00:01:16 0.577791 

のは、それをシャッフルしてみましょう:

In [132]: df = df.sample(frac=1) 

In [133]: df.head() 
Out[133]: 
          val 
1980-07-04 12:10:11 0.898648 
1980-07-08 20:37:39 0.563325 
1980-03-10 00:06:12 0.449458 
1980-08-07 02:01:42 0.511847 
1980-02-28 21:09:43 0.757327 

の保存は、NOTE(HDF5ファイルにDFを生成:唯一のインデックスがインデックス化され、デフォルトごとに、あなたが検索しようとしているので、もし他の列でもdata_columnsパラメータを使用してください)。

In [134]: store = pd.HDFStore('d:/temp/test_time_ser.h5') 

In [135]: store.append('XAU', df, format='t') 

In [136]: store.close() 

In [140]: store = pd.HDFStore('d:/temp/test_time_ser.h5') 

select(where="<query>")方法:

In [141]: store.select('XAU', where="index >= '1980-04-04' and index<= '1980-05-01'").head() 
Out[141]: 
          val 
1980-04-13 07:22:05 0.391409 
1980-04-25 14:23:07 0.400838 
1980-04-10 12:32:08 0.136346 
1980-04-09 18:58:35 0.944389 
1980-04-13 22:34:05 0.115643 

測定パフォーマンス:

In [144]: dates = pd.date_range(start='1980-04-04',end='1980-05-01', freq='S') 

In [145]: index = store.select_column('XAU','index') 

In [146]: store.select('XAU', where=index[index.isin(dates)].index).head() 
Out[146]: 
          val 
1980-04-13 07:22:05 0.391409 
1980-04-25 14:23:07 0.400838 
1980-04-10 12:32:08 0.136346 
1980-04-09 18:58:35 0.944389 
1980-04-13 22:34:05 0.115643 

In [147]: %timeit store.select('XAU', where=index[index.isin(dates)].index) 
1 loop, best of 3: 8.13 s per loop 

UPDATE:

In [142]: %timeit store.select('XAU', where="index >= '1980-04-04' and index<= '1980-05-01'") 
1 loop, best of 3: 755 ms per loop 

のは、あなたの現在のアプローチと比較してみましょうのは、同じテストをやらせるが、この時間はあると仮定インデックス(時系列)はソート

In [156]: df = pd.DataFrame({'val':np.random.rand(10**6)}, index=pd.date_range('1980-01-01', freq='19S', periods=10**6)) 

In [157]: df.shape 
Out[157]: (1000000, 1) 

In [164]: store.close() 

In [165]: store = pd.HDFStore('d:/temp/test_time_ser2.h5') 

In [166]: store.append('XAU', df, format='t') 

In [167]: %timeit store.select('XAU', where="index >= '1980-04-04' and index<= '1980-05-01'") 
1 loop, best of 3: 253 ms per loop 

In [168]: %timeit store.select('XAU', where=index[index.isin(dates)].index) 
1 loop, best of 3: 8.13 s per loop 
+0

これは素晴らしいです。ありがとうございます。あなたはとても親切で、最初の選択肢がより速い理由についての文章を書くことができますか? – Tim

+0

@Tim、IMO 'isin()'は、 "レンジ・スキャン"(Oracle Cost Base Optimizerの用語集)に比べて膨大なオーバーヘッドを持っています。リストからすべての値を系列(ベクトル)で比較する必要があります。範囲スキャン( '' index> = '1980-04-04'とindex <= '1980-05-01' "')を実行すると、2つの値(範囲の境界)を比較する必要があります – MaxU

+0

インデックスはソートされていますかHDFファイルかどうか?私たちのテストに影響を与えるかもしれません。私はそれがソートされていないと仮定しました – MaxU

関連する問題