2

パンダ、hdf5を使用してETLツールキットを構築しようとしています。

私の計画は

  1. mysqlからDataFrameにテーブルを抽出します。
  2. このDataFrameをHDFStoreに配置します。

しかし、ステップ2を実行しているときに、データフレームを*.h5ファイルに入れるのに時間がかかりすぎることに気付きました。

  • ソースmysqlサーバーのテーブルのサイズ:498MB
    • 52列
    • 924,624レコード
  • データフレームを内部に入れた後の*.h5ファイルのサイズ:513MB
    • 'put'操作のコストは849.345677137秒です

私の質問は次のとおり
です。今回の費用は通常ですか?
それを速くする方法はありますか?


アップデート1

ありがとうジェフ

  • 私のコードはとてもシンプルです:

    extract_store = HDFStore('extract_store.h5')
    extract_store ['df_staff'] = df_staff

  • 'ptdump -av file.h5'を試行するとエラーが発生しましたが、このh5ファイルからデータフレームオブジェクトをロードできました。

Tables.exceptions.HDF5ExtError:HDF5エラーバックトレース

H5Fopenのファイル"../../../src/H5F.c"、行1512、
ファイルを開くことができませんファイル "../../../src/H5F.c"、行1307、H5F_open
スーパーブロックファイル"../../../src/H5Fsuper.c"、305行目を読み取ることができません。H5F_super_readで
ファイル署名ファイル"../../../src/H5Fsuper.c"が見つかりません。 153行目、H5F_locate_signature
で有効なファイル署名が見つかりません

HDF5エラーバックトレースの終了

ファイル'extract_store.h5'を開く/作成できません

  • その他の情報:
    • パンダバージョン: '0.10.0'
    • os:ubuntuサーバー10.04 x86_64
    • CPU:8 * Intel(R)Xeon(R)CPU X5670 @ 2.93GHz
    • MemTotal:51634016 kB

パンダを0.10.1-devに更新して、再試行します。


アップデート2

  • パンダを「0.10.1.dev-6e2b6ea」に更新しました
  • しかし、時間コストは減少しませんでした。今回は884.15秒かかります。
  • 'ptdump-avfile.h5'の出力は次のとおりです。
    /(RootGroup)''  
      /._v_attrs(AttributeSet)、4つの属性:  
       [CLASS:='GROUP'、  
        PYTABLES_FORMAT_VERSION:= '2.0'、  
        タイトル:=''、  
        バージョン:= '1.0']  
    / df_bugs(グループ)''  
      /df_bugs._v_attrs(AttributeSet)、12個の属性:  
       [CLASS:='GROUP'、  
        タイトル:=''、  
        バージョン:= '1.0'、  
        axis0_variety:='通常'、  
        axis1_variety:='通常'、  
        block0_items_variety:='通常'、  
        block1_items_variety:='通常'、  
        block2_items_variety:='通常'、  
        nblocks:= 3、  
        ndim:= 2、  
        pandas_type:='フレーム'、  
        pandas_version:= '0.10.1']  
    / df_bugs / axis0(Array(52、))''  
      アトム:= StringAtom(itemsize = 19、shape =()、dflt ='')  
      maindim:= 0  
      フレーバー:='numpy'  
      byteorder:='無関係'  
      チャンクシェイプ:=なし  
      /df_bugs/axis0._v_attrs(AttributeSet)、7つの属性:  
       [クラス:='配列'、  
        フレーバー:='numpy'、  
        タイトル:=''、  
        バージョン:= '2.3'、  
        種類:='文字列'、  
        名前:=なし、  
        転置:= True]  
    / df_bugs / axis1(Array(924624、))''  
      アトム:= Int64Atom(shape =()、dflt = 0)  
      maindim:= 0  
      フレーバー:='numpy'  
      byteorder:='少し'  
      チャンクシェイプ:=なし  
      /df_bugs/axis1._v_attrs(AttributeSet)、7つの属性:  
       [クラス:='配列'、  
        フレーバー:='numpy'、  
        タイトル:=''、  
        バージョン:= '2.3'、  
        種類:='整数'、  
        名前:=なし、  
        転置:= True]  
    / df_bugs / block0_items(Array(5、))''  
      アトム:= StringAtom(itemsize = 12、shape =()、dflt ='')  
      maindim:= 0   
      フレーバー:='numpy'  
      byteorder:='無関係'  
      チャンクシェイプ:=なし  
      /df_bugs/block0_items._v_attrs(AttributeSet)、7つの属性:  
       [クラス:='配列'、  
        フレーバー:='numpy'、  
        タイトル:=''、  
        バージョン:= '2.3'、  
        種類:='文字列'、  
        名前:=なし、  
        転置:= True]  
    / df_bugs / block0_values(Array(924624、5))''  
      アトム:= Float64Atom(shape =()、dflt = 0.0)  
      maindim:= 0  
      フレーバー:='numpy'  
      byteorder:='少し'  
      チャンクシェイプ:=なし  
      /df_bugs/block0_values._v_attrs(AttributeSet)、5つの属性:  
       [クラス:='配列'、  
        フレーバー:='numpy'、  
        タイトル:=''、  
        バージョン:= '2.3'、  
        転置:= True]  
    / df_bugs / block1_items(Array(19、))''  
      アトム:= StringAtom(itemsize = 19、shape =()、dflt ='')  
      maindim:= 0  
      フレーバー:='numpy'  
      byteorder:='無関係'  
      チャンクシェイプ:=なし  
      /df_bugs/block1_items._v_attrs(AttributeSet)、7つの属性:  
       [クラス:='配列'、  
        フレーバー:='numpy'、  
        タイトル:=''、  
        バージョン:= '2.3'、  
        種類:='文字列'、  
        名前:=なし、  
        転置:= True]  
    / df_bugs / block1_values(Array(924624、19))''  
      アトム:= Int64Atom(shape =()、dflt = 0)  
      maindim:= 0  
      フレーバー:='numpy'  
      byteorder:='少し'  
      チャンクシェイプ:=なし  
      /df_bugs/block1_values._v_attrs(AttributeSet)、5つの属性:  
       [クラス:='配列'、  
        フレーバー:='numpy'、  
        タイトル:=''、   
        バージョン:= '2.3'、  
        転置:= True]  
    / df_bugs / block2_items(Array(28、))''  
      アトム:= StringAtom(itemsize = 18、shape =()、dflt ='')  
      maindim:= 0  
      フレーバー:='numpy'  
      byteorder:='無関係'  
      チャンクシェイプ:=なし  
      /df_bugs/block2_items._v_attrs(AttributeSet)、7つの属性:  
       [クラス:='配列'、  
        フレーバー:='numpy'、  
        タイトル:=''、  
        バージョン:= '2.3'、
        種類:='文字列'、  
        名前:=なし、  
        転置:= True]  
    / df_bugs / block2_values(VLArray(1、))''  
      アトム=ObjectAtom()  
      byteorder='無関係'  
      nrows = 1  
      フレーバー='numpy'  
      /df_bugs/block2_values._v_attrs(AttributeSet)、5つの属性:  
       [クラス:='VLARRAY'、  
        PSEUDOATOM:='オブジェクト'、  
        タイトル:=''、   
        バージョン:= '1.3'、  
        転置:= True]  
  • 以下のコードを試しましたが(パラメータ'table'がTrueの状態でデータフレームをhdfstoreに配置)、代わりにエラーが発生しました。Pythonのデータ時間タイプがサポートされていないようです。

例外:タイプ'datetime.datetime'の正しいアトムタイプ->[dtype->object]オブジェクトが見つかりませんlen()がありません


アップデート3

ジェフに感謝します。遅れて申し訳ありません。

  • テーブル。バージョン:「2.4.0」。
  • はい、884秒はmysqlからのプル操作なしのプット操作コストのみです
  • データフレームの行(df.ix [0]):
bug_id 1
185に割り当てられました
bug_file_locなし
bug_severityクリティカル
bug_statusclosed
Creation_ts 1998-05-06 21:27:00
delta_ts 2012-05-09 14:41:41
short_desc2つのカーソル。
host_op_sys不明
guest_op_sys不明
優先度P3
rep_platform IA32
レポーター56
product_id 7
category_id 983
component_id 12925
解像度が修正されました
target_milestone ws1
qa_contact 412
status_whiteboard                         
投票0
キーワードSR
lastdiffed 2012-05-09 14:41:41
確認済み1
reporter_accessible 1
cclist_accessible 1
推定時間0.00
残り時間0.00
締め切りなし
エイリアスなし
found_in_product_id 0
found_in_version_id 0
found_in_phase_id 0
cf_typeの欠陥
cf_reported_by開発
cf_attempted NaN
cf_failed NaN
cf_public_summary                         
cf_doc_impact 0
cf_security 0
cf_build NaN
cf_branch                                 
cf_change NaN
cf_test_id NaN
cf_regression不明
cf_reviewer 0
cf_on_hold 0
cf_public_severity ---
cf_i18n_impact 0
cf_etaなし
cf_bug_source ---
cf_vissなし
名前:0、長さ:52
  • データフレームの画像(ipythonノートブックで「df」と入力するだけ):
Int64Index:924624エントリ、0〜924623
データ列:
bug_id924624非null値
Assigned_to924624非null値
bug_file_loc427318非null値
bug_severity924624非null値
bug_status924624非null値
Creation_ts924624非null値
delta_ts924624非null値
short_desc924624非null値
host_op_sys924624非null値
guest_op_sys924624非null値
優先度924624null以外の値
rep_platform924624非null値
レポーター924624非ヌル値
product_id924624非null値
category_id924624非null値
component_id924624非null値
解像度924624null以外の値
target_milestone924624非null値
qa_contact924624非null値
status_whiteboard924624非null値
投票924624null以外の値
キーワード924624null以外の値
lastdiffed924509非null値
これまでに確認された924624非null値
reporter_accessible924624非null値
cclist_accessible924624非null値
Estimated_time924624非null値
残りの時間924624null以外の値
期限0のnull以外の値
エイリアス0のnull以外の値
found_in_product_id924624非null値
found_in_version_id924624非null値
found_in_phase_id924624非null値
cf_type924624非null値
cf_reported_by924624非null値
cf_attempted89622非null値
cf_failed89587非null値
cf_public_summary510799非null値
cf_doc_impact924624非null値
cf_security924624非null値
cf_build327460非null値
cf_branch614929非null値
cf_change300612非null値
cf_test_id12610非null値
cf_regression924624非null値
cf_reviewer924624非null値
cf_on_hold924624非null値
cf_public_severity924624非null値
cf_i18n_impact924624非null値
cf_eta3910非null値
cf_bug_source924624非null値
cf_viss725非null値
dtypes:float64(5)、int64(19)、object(28)
  • 'convert_objects()'の後:
dtypes:datetime64 [ns](2)、float64(5)、int64(19)、object(26)
  • 変換されたデータフレームをhdfstoreのコストに入れる:749.50秒:)
    • 'object' dtypesの数を減らすことが、時間コストを削減するための鍵のようです。
  • 変換されたデータフレームをパラメータ'table'がtrueのhdfstoreに入れると、それでもそのエラーが返されます
/usr/local/lib/python2.6/dist-packages/pandas-0.10.1.dev_6e2b6ea-py2.6-linux-x86_64.egg/pandas/io/pytables.pyc in create_axes(self、axes、obj、validate 、nan_rep、data_columns、min_itemsize、** kwargs)
   2203レイズ
   (例外)を除く2204、詳細:
-> 2205 raise Exception("正しいアトムタイプが見つかりません->[dtype->%s]%s"%(b.dtype.name、str(detail)))
   2206 j + = 1
   2207
例外:タイプ'datetime.datetime'の正しいアトムタイプ->[dtype->object]オブジェクトが見つかりませんlen()がありません
  • 日時列なしでデータフレームを配置しようとしています

アップデート4

  • mysqlには、datetime型の4つの列があります。
    • Creation_ts
    • delta_ts
    • lastdiffed
    • 締め切り

convert_objects()を呼び出した後:

  • Creation_ts:
タイムスタンプ:1998-05-06 21:27:00
  • delta_ts:
タイムスタンプ:2012-05-09 14:41:41
  • lastdiffed
datetime.datetime(2012、5、9、14、41、41)
  • 'convert_objects'の呼び出しの前後に関係なく、期限は常にNoneです。
なし
  • 列「lastdiff」なしでデータフレームを配置すると、691.75秒かかります
  • 列'lastdiff'なしでデータフレームを配置し、param'table'をTrueに設定すると、新しいエラーが発生しました。
/usr/local/lib/python2.6/dist-packages/pandas-0.10.1.dev_6e2b6ea-py2.6-linux-x86_64.egg/pandas/io/pytables.pyc in create_axes(self、axes、obj、validate 、nan_rep、data_columns、min_itemsize、** kwargs)
   2203レイズ
   (例外)を除く2204、詳細:
-> 2205 raise Exception("正しいアトムタイプが見つかりません->[dtype->%s]%s"%(b.dtype.name、str(detail)))
   2206 j + = 1
   2207

例外:タイプ'Decimal'の正しいアトムタイプ->[dtype->object]オブジェクトが見つかりませんlen()がありません
  • 列のタイプ'estimated_time'、'remaining_time'、'cf_viss'はmysqlでは'decimal'です

アップデート5

  • 以下のコードによって、これらの「decimal」タイプの列を「float」タイプに変換しました。
no_diffed_converted_df_bugs.estimated_time = no_diffed_converted_df_bugs.estimated_time.map(float)
  • そして今、時間コストは372.84秒です
  • しかし、「テーブル」バージョンのパッティングでもエラーが発生しました。
/usr/local/lib/python2.6/dist-packages/pandas-0.10.1.dev_6e2b6ea-py2.6-linux-x86_64.egg/pandas/io/pytables.pyc in create_axes(self、axes、obj、validate 、nan_rep、data_columns、min_itemsize、** kwargs)
   2203レイズ
   (例外)を除く2204、詳細:
-> 2205 raise Exception("正しいアトムタイプが見つかりません->[dtype->%s]%s"%(b.dtype.name、str(detail)))
   2206 j + = 1
   2207

例外:タイプ'datetime.date'の正しいアトムタイプ->[dtype->object]オブジェクトが見つかりませんlen()がありません
4

2 に答える 2

4

あなたの問題は、DataFramesの実際の型の型マッピングと、それらがPyTablesによってどのように格納されるかに関連していると私はかなり確信しています。

  • 固定表現を持つ単純なタイプ(floats / ints / bools)、これらは固定cタイプにマップされます
  • 日時は、適切に変換できる場合に処理されます(たとえば、dtypeが'datetime64 [ns]'である場合、特にdatetimes.dateは処理されません(NaNは別のストーリーであり、使用法によっては列タイプ全体が誤って処理される可能性があります)
  • 文字列はマップされます(Storerオブジェクトではオブジェクトタイプにマップされ、Tableはそれらを文字列タイプにマップします)
  • Unicodeは処理されません
  • 他のすべてのタイプは、Storersでオブジェクトとして処理されるか、テーブルに対して例外がスローされます

これが意味するのは、Storer(固定表現)にプットを実行している場合、マップ不可能なタイプはすべてオブジェクトになるということです。これを参照してください。PyTablesはこれらの列をピクルスにします。ObjectAtomについては、以下のリファレンスを参照してください

http://pytables.github.com/usersguide/libref/declarative_classes.html#the-atom-class-and-its-descendants

テーブルは無効なタイプで発生します(ここでより良いエラーメッセージを提供する必要があります)。ObjectAtomにマップされているタイプを保存しようとすると(パフォーマンス上の理由から)、警告も提供すると思います。

一部のタイプを強制するには、次のいくつかを試してください。

import pandas as pd

# convert None to nan (its currently Object)
# converts to float64 (or type of other objs)
x = pd.Series([None])
x = x.where(pd.notnull(x)).convert_objects()

# convert datetime like with embeded nans to datetime64[ns]
df['foo'] = pd.Series(df['foo'].values, dtype = 'M8[ns]')

これが64ビットLinuxのサンプルです(ファイルは1M行、ディスク上のサイズは約1 GBです)

In [1]: import numpy as np

In [2]: import pandas as pd

In [3]: pd.__version__
Out[3]: '0.10.1.dev'

In [3]: import tables

In [4]: tables.__version__
Out[4]: '2.3.1'

In [4]: df = pd.DataFrame(np.random.randn(1000 * 1000, 100), index=range(int(
   ...: 1000 * 1000)), columns=['E%03d' % i for i in xrange(100)])

In [5]: for x in range(20):
   ...:     df['String%03d' % x] = 'string%03d' % x

In [6]: df
Out[6]: 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000000 entries, 0 to 999999
Columns: 120 entries, E000 to String019
dtypes: float64(100), object(20)

# storer put (cannot query) 
In [9]: def test_put():
   ...:     store = pd.HDFStore('test_put.h5','w')
   ...:     store['df'] = df
   ...:     store.close()

In [10]: %timeit test_put()
1 loops, best of 3: 7.65 s per loop

# table put (can query)
In [7]: def test_put():
      ....:     store = pd.HDFStore('test_put.h5','w')
      ....:     store.put('df',df,table=True)
      ....:     store.close()


In [8]: %timeit test_put()
1 loops, best of 3: 21.4 s per loop
于 2013-01-17T00:11:12.833 に答える
2

これを速くする方法は?

  1. 'io.sql.read_frame'を使用して、SQLデータベースからデータフレームにデータをロードします。'read_frame'は、タイプが'decimal'の列をfloatに変換することで処理するためです。
  2. 各列の欠落データを入力します。
  3. 操作を行う前に、関数'DataFrame.convert_objects'を呼び出します
  4. 日付フレームに文字列型の列がある場合は、「storer」ではなく「table」を使用してください

store.put('key'、df、table = True)

これらのジョブを実行した後、同じデータセットを使用すると、パッティング操作のパフォーマンスが大幅に向上します。

CPU times: user 42.07 s, sys: 28.17 s, total: 70.24 s
Wall time: 98.97 s

2番目のテストのプロファイルログ:

68.688 CPU秒で95984関数呼び出し(95958プリミティブ呼び出し)

   注文者:内部時間

   ncalls tottime percall cumtime percallファイル名:lineno(関数)
      445 16.757 0.038 16.757 0.038 {numpy.core.multiarray.array}
       19 16.250 0.855 16.2500.855{'tables.tableExtension.Table'オブジェクトのメソッド'_append_records'}
       16 7.958 0.497 7.9580.497{メソッド'astype'of'numpy.ndarray'オブジェクト}
       19 6.533 0.344 6.533 0.344 {pandas.lib.create_hdf_rows_2d}
        4 6.284 1.571 6.3881.597{'tables.tableExtension.Row'オブジェクトのメソッド'_fillCol'}
       20 2.640 0.132 2.641 0.132 {pandas.lib.maybe_convert_objects}
        1 1.785 1.785 1.785 1.785 {pandas.lib.isnullobj}
        7 1.619 0.231 1.6190.231{メソッド'flatten'of'numpy.ndarray'オブジェクト}
       11 1.059 0.096 1.059 0.096 {pandas.lib.infer_dtype}
        1 0.997 0.997 41.952 41.952 pytables.py:2468(write_data)
       19 0.985 0.052 40.590 2.136 pytables.py:2504(write_data_chunk)
        1 0.827 0.827 60.617 60.617 pytables.py:2433(書き込み)
     1504 0.592 0.000 0.5920.000{'tables.hdf5Extension.Array'オブジェクトのメソッド'_g_readSlice'}
        4 0.534 0.133 13.676 3.419 pytables.py:1038(set_atom)
        1 0.528 0.528 0.528 0.528 {pandas.lib.max_len_string_array}
        4 0.441 0.110 0.571 0.143 internals.py:1409(_stack_arrays)
       35 0.358 0.010 0.3580.010{メソッド'copy'of'numpy.ndarray'オブジェクト}
        1 0.276 0.276 3.135 3.135 internals.py:208(fillna)
        5 0.263 0.053 2.054 0.411 common.py:128(_isnull_ndarraylike)
       48 0.253 0.005 0.2530.005{'tables.hdf5Extension.Array'オブジェクトのメソッド'_append'}
        4 0.240 0.060 1.500 0.375 internals.py:1400(_simple_blockify)
        1 0.234 0.234 12.145 12.145 pytables.py:1066(set_atom_string)
       28 0.225 0.008 0.2250.008{'tables.hdf5Extension.Array'オブジェクトのメソッド'_createCArray'}
       36 0.218 0.006 0.2180.006{'tables.hdf5Extension.Array'オブジェクトのメソッド'_g_writeSlice'}
     6110 0.155 0.000 0.155 0.000 {numpy.core.multiarray.empty}
        4 0.097 0.024 0.0970.024{メソッド'all'of'numpy.ndarray'オブジェクト}
        6 0.084 0.014 0.084 0.014 {tables.indexesExtension.keysort}
       18 0.084 0.005 0.0840.005{'tables.hdf5Extension.Leaf'オブジェクトのメソッド'_g_close'}
    11816 0.064 0.000 0.108 0.000 file.py:1036(_getNode)
       19 0.053 0.003 0.0530.003{'tables.hdf5Extension.Leaf'オブジェクトのメソッド'_g_flush'}
     1528 0.045 0.000 0.098 0.000 array.py:342(_interpret_indexing)
    11709 0.040 0.000 0.042 0.000 file.py:248(__getitem__)
        2 0.027 0.013 0.383 0.192 index.py:1099(get_neworder)
        1 0.018 0.018 0.018 0.018 {numpy.core.multiarray.putmask}
        4 0.013 0.003 0.017 0.004 index.py:607(final_idx32)
于 2013-01-23T07:43:24.723 に答える