2013-06-08 13 views
12

統計処理用に大量のhttpログ(80GB +)をPandas HDFStoreにインポートしています。単一のインポートファイル内であっても、ロードするときにコンテンツをバッチする必要があります。これまでの私のやり方は、解析された行をDataFrameに読み込んだ後、DataFrameをHDFStoreに保存することでした。私の目標は、データストア内の単一のキーに対してインデックスキーをユニークにすることですが、各DataFrameはそれ自身のインデックス値を再開します。私はHDFStore.append()がDataFrameのインデックス値を無視し、HDFStoreキーの既存のインデックス値を追加し続けるように指示するメカニズムを持っていると予想していましたが、見つからないようです。 HDFStoreに既存のインデックス値をインクリメントさせながら、DataFramesをインポートし、そこに含まれるインデックス値を無視するにはどうすればよいですか? 10行ごとにバッチのサンプルコード。当然のことながら、実際のものはもっと大きくなります。Pandas HDFStoreにどのように大量のデータを追加し、自然なユニークなインデックスを得るには?

if hd_file_name: 
     """ 
     HDF5 output file specified. 
     """ 

     hdf_output = pd.HDFStore(hd_file_name, complib='blosc') 
     print hdf_output 

     columns = ['source', 'ip', 'unknown', 'user', 'timestamp', 'http_verb', 'path', 'protocol', 'http_result', 
        'response_size', 'referrer', 'user_agent', 'response_time'] 

     source_name = str(log_file.name.rsplit('/')[-1]) # HDF5 Tables don't play nice with unicode so explicit str(). :(

     batch = [] 

     for count, line in enumerate(log_file,1): 
      data = parse_line(line, rejected_output = reject_output) 

      # Add our source file name to the beginning. 
      data.insert(0, source_name)  
      batch.append(data) 

      if not (count % 10): 
       df = pd.DataFrame(batch, columns = columns) 
       hdf_output.append(KEY_NAME, df) 
       batch = [] 

     if (count % 10): 
      df = pd.DataFrame(batch, columns = columns) 
      hdf_output.append(KEY_NAME, df) 
+0

あなたは[この回答を読んでいる](http://stackoverflow.com/a/14268804/1240268)? –

答えて

13

このようにすることができます。最初はストアテーブルが存在しないので、get_storerが発生します。 (あなたは1を望んでいない限り)あなたが実際に必ずしも(PyTables経由)HDFStoreとして、グローバルな一意のインデックスを必要としません

import pandas as pd 
import numpy as np 
import os 

files = ['test1.csv','test2.csv'] 
for f in files: 
    pd.DataFrame(np.random.randn(10,2),columns=list('AB')).to_csv(f) 

path = 'test.h5' 
if os.path.exists(path): 
    os.remove(path) 

with pd.get_store(path) as store: 
    for f in files: 
     df = pd.read_csv(f,index_col=0) 
     try: 
      nrows = store.get_storer('foo').nrows 
     except: 
      nrows = 0 

     df.index = pd.Series(df.index) + nrows 
     store.append('foo',df) 


In [10]: pd.read_hdf('test.h5','foo') 
Out[10]: 
      A   B 
0 0.772017 0.153381 
1 0.304131 0.368573 
2 0.995465 0.799655 
3 -0.326959 0.923280 
4 -0.808376 0.449645 
5 -1.336166 0.236968 
6 -0.593523 -0.359080 
7 -0.098482 0.037183 
8 0.315627 -1.027162 
9 -1.084545 -1.922288 
10 0.412407 -0.270916 
11 1.835381 -0.737411 
12 -0.607571 0.507790 
13 0.043509 -0.294086 
14 -0.465210 0.880798 
15 1.181344 0.354411 
16 0.501892 -0.358361 
17 0.633256 0.419397 
18 0.932354 -0.603932 
19 -0.341135 2.453220 

は一意の番号行ずつを提供します。これらの選択パラメータはいつでも追加できます。

In [11]: pd.read_hdf('test.h5','foo',start=12,stop=15) 
Out[11]: 
      A   B 
12 -0.607571 0.507790 
13 0.043509 -0.294086 
14 -0.465210 0.880798 
+0

グレートポスト;ただし、このような回避策の代わりに自動インクリメンタルインデックスを持つのが理想的な場合(これらのような場合)があります。次のように:hdf5に保存すると、ignore_index = True(pd.Concatのような)を持つことができ、自動的にこれを実行しますか?単なるアイデア – Carst

+0

また、大量の小さなファイルを使用する場合は、現在の行数を取得し、各追加アクションの終わりに現在のデータフレームの長さで毎回上向きに上書きする方がよいでしょう。 )。これがあいまいなコメントであれば教えてください。私はどこかでそれを動作させます。 – Carst

+0

あなたは本当にこれらのどちらかをする必要はありません。店舗は内部で番号が付けられていますので、必要に応じて行番号で選択することができます(こちらを参照)[http://pandas.pydata.org/pandas-docs/dev/io.html#advanced-queries] – Jeff

関連する問題