web-dev-qa-db-ja.com

pandas(PyTables?)HDF5テーブル書き込みパフォーマンスの向上

私はpandasを現在2か月間研究に使用して大きな効果を上げています。中規模のトレースイベントデータセットが多数ある場合、pandas + PyTables( HDF5インターフェース)は、Python私が知っている、大好きなすべてのツールを使用して、異種データを処理できるようにするという途方もない仕事をします。

一般的に言って、PyTablesでは固定(以前の "Storer")形式を使用します。これは、ワークフローが追記型、読み取り多型であり、データセットの多くは、それらの50〜100個をメモリにロードできるサイズになっているためです。重大な不利益のない時間。 (注:私の仕事の大部分は、128 GB以上のシステムメモリを搭載したOpteronサーバークラスマシンで行っています。)

ただし、大規模なデータセット(500 MB以上)では、PyTablesの「テーブル」形式のよりスケーラブルなランダムアクセスおよびクエリ機能を使用できるようにしたいので、クエリをメモリ不足で実行できます。処理のために、はるかに小さい結果セットをメモリにロードします。ただし、ここでの大きなハードルは書き込みパフォーマンスです。はい、私が言ったように、私のワークフローは一度だけ、多くの読み取りですが、相対的な時間はまだ受け入れられません。

例として、私は最近、48コアマシンで3分8秒(188秒)かかった大規模なコレスキー分解を実行しました。これにより、約2.2 GBのトレースファイルが生成されました。トレースはプログラムと並行して生成されるため、追加の「トレース作成時間」はありません。

バイナリトレースファイルをpandas/PyTables形式に最初に変換するにはかなりの時間がかかりますが、これは主に、バイナリ形式が意図的に順序が狂っていて、トレースジェネレータ自体のパフォーマンスへの影響を減らすためです。これは、Storer形式からTable形式に移行する際のパフォーマンスの低下とは無関係です。

私のテストはpandas 0.12、numpy 1.7.1、PyTables 2.4.0、およびnumexpr 0.20.1で最初に実行されました。私の48コアマシンはコアあたり2.8GHzで実行され、 SSD上にある(確かではない)ext3ファイルシステム。

データセット全体を7.1秒でStorer形式のHDF5ファイル(結果のファイルサイズ:3.3GB)に書き込むことができます。テーブル形式で書き込まれた同じデータセット(結果のファイルサイズも3.3 GB)は、書き込みに178.7秒かかります。

コードは次のとおりです。

with Timer() as t:
    store = pd.HDFStore('test_storer.h5', 'w')
    store.put('events', events_dataset, table=False, append=False)
print('Fixed format write took ' + str(t.interval))
with Timer() as t:
    store = pd.HDFStore('test_table.h5', 'w')
    store.put('events', events_dataset, table=True, append=False)
print('Table format write took ' + str(t.interval))

そして出力は単純です

Fixed format write took 7.1
Table format write took 178.7

私のデータセットには28,880,943行があり、列は基本的なデータ型です。

node_id           int64
thread_id         int64
handle_id         int64
type              int64
begin             int64
end               int64
duration          int64
flags             int64
unique_id         int64
id                int64
DSTL_LS_FULL    float64
L2_DMISS        float64
L3_MISS         float64
kernel_type     float64
dtype: object

...そのため、書き込み速度にデータ固有の問題があるとは思いません。

また、BLOSC圧縮を追加して、いずれかのシナリオに影響を与える可能性がある奇妙なI/O問題を排除しようとしましたが、圧縮によって両方のパフォーマンスが等しく低下するようです。

pandasのドキュメントには、Storer形式の方が書き込みが大幅に速く、読み取りがわずかに速いと記載されていることがわかりました(Storer形式の読み取りには時間がかかるようで、テーブルフォーマットの読み取りには約10秒かかりますが、約2.5秒です。しかし、テーブルフォーマットの書き込みにStorerフォーマットの書き込みの25倍の時間がかかることは、実際には過度に思えます。

PyTablesまたはpandas=に関係している人は、クエリ可能な形式(明らかに追加のデータがほとんど必要ない)への書き込みが桁違いに長くなる理由)の(またはその他の)理由を説明できますか?そして、これを将来的に改善する希望はありますか?私の分野はハイパフォーマンスコンピューティングであり、このドメインの両方のプロジェクトの重要なユースケースを見ているので、どちらかのプロジェクトへの貢献に飛び込みたいです。 ..しかし、最初に関係する問題についていくつかの明確化、および/またはシステムがどのように構築されているかを知っている人から物事をスピードアップする方法についてのいくつかのアドバイスを得ることは役立つでしょう。

編集:

IPythonで%prunを使用して前のテストを実行すると、Storer/Fixed形式の次の(読みやすくするために多少削減された)プロファイル出力が得られます。

%prun -l 20 profile.events.to_hdf('test.h5', 'events', table=False, append=False)

3223 function calls (3222 primitive calls) in 7.385 seconds

Ordered by: internal time
List reduced from 208 to 20 due to restriction <20>

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    6    7.127    1.188    7.128    1.188 {method '_createArray' of 'tables.hdf5Extension.Array' objects}
    1    0.242    0.242    0.242    0.242 {method '_closeFile' of 'tables.hdf5Extension.File' objects}
    1    0.003    0.003    0.003    0.003 {method '_g_new' of 'tables.hdf5Extension.File' objects}
   46    0.001    0.000    0.001    0.000 {method 'reduce' of 'numpy.ufunc' objects}

テーブル形式の場合は次のようになります。

   %prun -l 40 profile.events.to_hdf('test.h5', 'events', table=True, append=False, chunksize=1000000)

   499082 function calls (499040 primitive calls) in 188.981 seconds

   Ordered by: internal time
   List reduced from 526 to 40 due to restriction <40>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       29   92.018    3.173   92.018    3.173 {pandas.lib.create_hdf_rows_2d}
      640   20.987    0.033   20.987    0.033 {method '_append' of 'tables.hdf5Extension.Array' objects}
       29   19.256    0.664   19.256    0.664 {method '_append_records' of 'tables.tableExtension.Table' objects}
      406   19.182    0.047   19.182    0.047 {method '_g_writeSlice' of 'tables.hdf5Extension.Array' objects}
    14244   10.646    0.001   10.646    0.001 {method '_g_readSlice' of 'tables.hdf5Extension.Array' objects}
      472   10.359    0.022   10.359    0.022 {method 'copy' of 'numpy.ndarray' objects}
       80    3.409    0.043    3.409    0.043 {tables.indexesExtension.keysort}
        2    3.023    1.512    3.023    1.512 common.py:134(_isnull_ndarraylike)
       41    2.489    0.061    2.533    0.062 {method '_fillCol' of 'tables.tableExtension.Row' objects}
       87    2.401    0.028    2.401    0.028 {method 'astype' of 'numpy.ndarray' objects}
       30    1.880    0.063    1.880    0.063 {method '_g_flush' of 'tables.hdf5Extension.Leaf' objects}
      282    0.824    0.003    0.824    0.003 {method 'reduce' of 'numpy.ufunc' objects}
       41    0.537    0.013    0.668    0.016 index.py:607(final_idx32)
    14490    0.385    0.000    0.712    0.000 array.py:342(_interpret_indexing)
       39    0.279    0.007   19.635    0.503 index.py:1219(reorder_slice)
        2    0.256    0.128   10.063    5.031 index.py:1099(get_neworder)
        1    0.090    0.090  119.392  119.392 pytables.py:3016(write_data)
    57842    0.087    0.000    0.087    0.000 {numpy.core.multiarray.empty}
    28570    0.062    0.000    0.107    0.000 utils.py:42(is_idx)
    14164    0.062    0.000    7.181    0.001 array.py:711(_readSlice)

編集2:

pandas 0.13(2013年11月20日11:00 ESTにプルされた)のプレリリースコピーで再度実行すると、テーブル形式の書き込み時間が大幅に改善されますが、「合理的に」比較されません。 Storer/Fixedフォーマットの書き込み速度に。

%prun -l 40 profile.events.to_hdf('test.h5', 'events', table=True, append=False, chunksize=1000000)

         499748 function calls (499720 primitive calls) in 117.187 seconds

   Ordered by: internal time
   List reduced from 539 to 20 due to restriction <20>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      640   22.010    0.034   22.010    0.034 {method '_append' of 'tables.hdf5Extension.Array' objects}
       29   20.782    0.717   20.782    0.717 {method '_append_records' of 'tables.tableExtension.Table' objects}
      406   19.248    0.047   19.248    0.047 {method '_g_writeSlice' of 'tables.hdf5Extension.Array' objects}
    14244   10.685    0.001   10.685    0.001 {method '_g_readSlice' of 'tables.hdf5Extension.Array' objects}
      472   10.439    0.022   10.439    0.022 {method 'copy' of 'numpy.ndarray' objects}
       30    7.356    0.245    7.356    0.245 {method '_g_flush' of 'tables.hdf5Extension.Leaf' objects}
       29    7.161    0.247   37.609    1.297 pytables.py:3498(write_data_chunk)
        2    3.888    1.944    3.888    1.944 common.py:197(_isnull_ndarraylike)
       80    3.581    0.045    3.581    0.045 {tables.indexesExtension.keysort}
       41    3.248    0.079    3.294    0.080 {method '_fillCol' of 'tables.tableExtension.Row' objects}
       34    2.744    0.081    2.744    0.081 {method 'ravel' of 'numpy.ndarray' objects}
      115    2.591    0.023    2.591    0.023 {method 'astype' of 'numpy.ndarray' objects}
      270    0.875    0.003    0.875    0.003 {method 'reduce' of 'numpy.ufunc' objects}
       41    0.560    0.014    0.732    0.018 index.py:607(final_idx32)
    14490    0.387    0.000    0.712    0.000 array.py:342(_interpret_indexing)
       39    0.303    0.008   19.617    0.503 index.py:1219(reorder_slice)
        2    0.288    0.144   10.299    5.149 index.py:1099(get_neworder)
    57871    0.087    0.000    0.087    0.000 {numpy.core.multiarray.empty}
        1    0.084    0.084   45.266   45.266 pytables.py:3424(write_data)
        1    0.080    0.080   55.542   55.542 pytables.py:3385(write)

これらのテストを実行していると、書き込みが「一時停止」しているように見える長期間(ディスク上のファイルが活発に成長していない)であることに気づきましたが、これらの期間の一部ではCPU使用率も低くなっています。

いくつかの既知のext3制限がpandasまたはPyTablesのいずれかと不適切に相互作用する可能性があると疑い始めます。Ext3および他の非エクステントベースのファイルシステムは、大きなファイルのリンクをすばやく解除するのに苦労し、同様のシステムパフォーマンス(低たとえば、CPU使用率、ただし待機時間が長い)は、たとえば1GBファイルの単純な「rm」の間でも明らかです。

明確にするために、各テストケースで、ext3ファイルの削除/上書きのペナルティが発生しないように、テストを開始する前に既存のファイルがあれば削除することを確認しました。

ただし、index = Noneを指定してこのテストを再実行すると、パフォーマンスが大幅に向上します(インデックス作成時の〜120に対して〜50s)。したがって、このプロセスは引き続きCPUにバインドされているように見えます(私のシステムには2.8GHzで実行されている比較的古いAMD Opteron Istanbul CPUがありますが、それぞれに6つのコアCPUを備えた8つのソケットがあり、そのうちの1つを除いて、もちろん、書き込み中はアイドル状態にしてください)、またはPyTablesまたはpandasがファイルシステム上ですでに部分的または完全にファイルを操作/読み取り/分析しようとする方法の間にいくつかの矛盾があるため、病理学的にインデックス作成が行われているときのI/O動作が不適切です。

編集3:

PyTablesを2.4から3.0.0にアップグレードした後、@ Jeffが推奨するより小さなデータセット(ディスク上で1.3 GB)でのテストは、ここに私を連れてきました:

In [7]: %timeit f(df)
1 loops, best of 3: 3.7 s per loop

In [8]: %timeit f2(df) # where chunksize= 2 000 000
1 loops, best of 3: 13.8 s per loop

In [9]: %timeit f3(df) # where chunksize= 2 000 000
1 loops, best of 3: 43.4 s per loop

実際、インデックス作成がオンになっている場合(デフォルト)を除き、私のパフォーマンスはすべてのシナリオで彼を上回っています。ただし、インデックス作成は依然としてキラーであり、これらのテストを実行するときにtoplsからの出力を解釈する方法が正しい場合は、重要な処理もファイルの書き込みも行われていません(つまり、PythonプロセスのCPU使用率は0に近く、ファイルサイズは一定のままです)。これらはファイルの読み取りであるとしか想定できません。なぜファイルの読み取りが3秒未満でこのディスクからメモリに3 GB以上のファイル全体を確実にロードできるため、スローダウンを引き起こすのは理解しにくいものです。それらがファイルの読み取りでない場合、システムは何を「待機」していますか?(他にだれもマシンにログインしておらず、他にファイルシステムのアクティビティはありません。)

この時点で、関連するpythonモジュールのアップグレードされたバージョンを使用すると、元のデータセットのパフォーマンスは次の数値まで低下します。特に興味深いのは、システム時間です。少なくともIOの実行に費やされた時間の上限、およびウォールタイム。これはおそらく、書き込み/ CPUアクティビティがないこれらの不可思議な期間を説明しているようです。

In [28]: %time f(profile.events)
CPU times: user 0 ns, sys: 7.16 s, total: 7.16 s
Wall time: 7.51 s

In [29]: %time f2(profile.events)
CPU times: user 18.7 s, sys: 14 s, total: 32.7 s
Wall time: 47.2 s

In [31]: %time f3(profile.events)
CPU times: user 1min 18s, sys: 14.4 s, total: 1min 32s
Wall time: 2min 5s

それにもかかわらず、インデックス作成は私のユースケースで大幅な速度低下を引き起こすようです。おそらく、デフォルトのケースを実行するのではなく、インデックス付けされたフィールドを制限する必要があります(DataFrameのすべてのフィールドでインデックス付けされている可能性があります)?これがクエリ時間にどのように影響する可能性があるか、特にクエリが非インデックスフィールドに基づいて選択する場合はわかりません。

Jeffの要求に従って、結果のファイルのptdump。

ptdump -av test.h5
/ (RootGroup) ''
  /._v_attrs (AttributeSet), 4 attributes:
   [CLASS := 'GROUP',
    PYTABLES_FORMAT_VERSION := '2.1',
    TITLE := '',
    VERSION := '1.0']
/df (Group) ''
  /df._v_attrs (AttributeSet), 14 attributes:
   [CLASS := 'GROUP',
    TITLE := '',
    VERSION := '1.0',
    data_columns := [],
    encoding := None,
    index_cols := [(0, 'index')],
    info := {1: {'type': 'Index', 'names': [None]}, 'index': {}},
    levels := 1,
    nan_rep := 'nan',
    non_index_axes := 
    [(1, ['node_id', 'thread_id', 'handle_id', 'type', 'begin', 'end', 'duration', 'flags', 'unique_id', 'id', 'DSTL_LS_FULL', 'L2_DMISS', 'L3_MISS', 'kernel_type'])],
    pandas_type := 'frame_table',
    pandas_version := '0.10.1',
    table_type := 'appendable_frame',
    values_cols := ['values_block_0', 'values_block_1']]
/df/table (Table(28880943,)) ''
  description := {
  "index": Int64Col(shape=(), dflt=0, pos=0),
  "values_block_0": Int64Col(shape=(10,), dflt=0, pos=1),
  "values_block_1": Float64Col(shape=(4,), dflt=0.0, pos=2)}
  byteorder := 'little'
  chunkshape := (4369,)
  autoindex := True
  colindexes := {
    "index": Index(6, medium, shuffle, zlib(1)).is_csi=False}
  /df/table._v_attrs (AttributeSet), 15 attributes:
   [CLASS := 'TABLE',
    FIELD_0_FILL := 0,
    FIELD_0_NAME := 'index',
    FIELD_1_FILL := 0,
    FIELD_1_NAME := 'values_block_0',
    FIELD_2_FILL := 0.0,
    FIELD_2_NAME := 'values_block_1',
    NROWS := 28880943,
    TITLE := '',
    VERSION := '2.7',
    index_kind := 'integer',
    values_block_0_dtype := 'int64',
    values_block_0_kind := ['node_id', 'thread_id', 'handle_id', 'type', 'begin', 'end', 'duration', 'flags', 'unique_id', 'id'],
    values_block_1_dtype := 'float64',
    values_block_1_kind := ['DSTL_LS_FULL', 'L2_DMISS', 'L3_MISS', 'kernel_type']]

更新されたモジュールと完全なデータセットを含む別の%prun:

%prun -l 25  %time f3(profile.events)
CPU times: user 1min 14s, sys: 16.2 s, total: 1min 30s
Wall time: 1min 48s

        542678 function calls (542650 primitive calls) in 108.678 seconds

   Ordered by: internal time
   List reduced from 629 to 25 due to restriction <25>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      640   23.633    0.037   23.633    0.037 {method '_append' of 'tables.hdf5extension.Array' objects}
       15   20.852    1.390   20.852    1.390 {method '_append_records' of 'tables.tableextension.Table' objects}
      406   19.584    0.048   19.584    0.048 {method '_g_write_slice' of 'tables.hdf5extension.Array' objects}
    14244   10.591    0.001   10.591    0.001 {method '_g_read_slice' of 'tables.hdf5extension.Array' objects}
      458    9.693    0.021    9.693    0.021 {method 'copy' of 'numpy.ndarray' objects}
       15    6.350    0.423   30.989    2.066 pytables.py:3498(write_data_chunk)
       80    3.496    0.044    3.496    0.044 {tables.indexesextension.keysort}
       41    3.335    0.081    3.376    0.082 {method '_fill_col' of 'tables.tableextension.Row' objects}
       20    2.551    0.128    2.551    0.128 {method 'ravel' of 'numpy.ndarray' objects}
      101    2.449    0.024    2.449    0.024 {method 'astype' of 'numpy.ndarray' objects}
       16    1.789    0.112    1.789    0.112 {method '_g_flush' of 'tables.hdf5extension.Leaf' objects}
        2    1.728    0.864    1.728    0.864 common.py:197(_isnull_ndarraylike)
       41    0.586    0.014    0.842    0.021 index.py:637(final_idx32)
    14490    0.292    0.000    0.616    0.000 array.py:368(_interpret_indexing)
        2    0.283    0.142   10.267    5.134 index.py:1158(get_neworder)
      274    0.251    0.001    0.251    0.001 {method 'reduce' of 'numpy.ufunc' objects}
       39    0.174    0.004   19.373    0.497 index.py:1280(reorder_slice)
    57857    0.085    0.000    0.085    0.000 {numpy.core.multiarray.empty}
        1    0.083    0.083   35.657   35.657 pytables.py:3424(write_data)
        1    0.065    0.065   45.338   45.338 pytables.py:3385(write)
    14164    0.065    0.000    7.831    0.001 array.py:615(__getitem__)
    28570    0.062    0.000    0.108    0.000 utils.py:47(is_idx)
       47    0.055    0.001    0.055    0.001 {numpy.core.multiarray.arange}
    28570    0.050    0.000    0.090    0.000 leaf.py:397(_process_range)
    87797    0.048    0.000    0.048    0.000 {isinstance}
32
Peter Gaultney

それは興味深い議論です。ピーターは、固定形式でシングルショットで書き込みを行うほか、SSDが非常に優れている(450 MB /秒を超えて書き込むことができる)ため、素晴らしいパフォーマンスを発揮していると思います。

テーブルへの追加は、より複雑な操作です(データセットを拡大する必要があり、新しいレコードをチェックして、それらがテーブルのスキーマに従っていることを確認できるようにする必要があります)。これが、テーブルへの行の追加が一般的に遅い理由です(ただし、それでもJeffは70 MB /秒を取得しています。これはかなり良いことです)。ジェフがピーターよりも速度を上げているのは、おそらく彼がより良いプロセッサを持っているという事実が原因です。

最後に、PyTablesでのインデックス作成は単一のプロセッサを使用します。通常、これは負荷の高い操作であるため、ディスク上のデータにクエリを実行しない場合は、実際に無効にする必要があります。

5
Francesc

ここに私がやったのと同じような比較があります。データの約1/3は10M行です。最終的なサイズは約1.3GBです

3つのタイミング関数を定義します。

固定形式(0.12ではStorerと呼ばれます)をテストします。これはPyTables配列形式で書き込みます

def f(df):
    store = pd.HDFStore('test.h5','w')
    store['df'] = df
    store.close()

PyTablesテーブル形式を使用して、テーブル形式で書き込みます。インデックスを作成しないでください。

def f2(df):
    store = pd.HDFStore('test.h5','w')
    store.append('df',df,index=False)
    store.close()

F2と同じですが、インデックスを作成します(これは通常行われます)

def f3(df):
    store = pd.HDFStore('test.h5','w')
    store.append('df',df)
    store.close()

フレームを作成する

In [25]: df = concat([DataFrame(np.random.randn(10000000,10)),DataFrame(np.random.randint(0,10,size=50000000).reshape(10000000,5))],axis=1)

In [26]: df
Out[26]:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10000000 entries, 0 to 9999999
Columns: 15 entries, 0 to 4
dtypes: float64(10), int64(5)


v0.12.0

In [27]: %timeit f(df)
1 loops, best of 3: 14.7 s per loop

In [28]: %timeit f2(df)
1 loops, best of 3: 32 s per loop

In [29]: %timeit f3(df)
1 loops, best of 3: 40.1 s per loop

master/v0.13.0

In [5]: %timeit f(df)
1 loops, best of 3: 12.9 s per loop

In [6]: %timeit f2(df)
1 loops, best of 3: 17.5 s per loop

In [7]: %timeit f3(df)
1 loops, best of 3: 24.3 s per loop

OPによって提供されるのと同じファイルでタイミング実行(リンクは以下)

In [4]: df = pd.read_hdf('test.h5','df')

In [5]: df
Out[5]: 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 28880943 entries, 0 to 28880942
Columns: 14 entries, node_id to kernel_type
dtypes: float64(4), int64(10)

F1と同様、固定形式

In [6]: %timeit df.to_hdf('test.hdf','df',mode='w')
1 loops, best of 3: 36.2 s per loop

F2と同様、テーブル形式、インデックスなし

In [7]: %timeit df.to_hdf('test.hdf','df',mode='w',format='table',index=False)
1 loops, best of 3: 45 s per loop

In [8]: %timeit df.to_hdf('test.hdf','df',mode='w',format='table',index=False,chunksize=2000000)
1 loops, best of 3: 44.5 s per loop

F3と同様に、インデックス付きのテーブル形式

In [9]: %timeit df.to_hdf('test.hdf','df',mode='w',format='table',chunksize=2000000)
1 loops, best of 3: 1min 36s per loop

F3と同様に、bloscで圧縮されたインデックス付きのテーブル形式

In [10]: %timeit df.to_hdf('test.hdf','df',mode='w',format='table',chunksize=2000000,complib='blosc')
1 loops, best of 3: 46.5 s per loop

In [11]: %timeit pd.read_hdf('test.hdf','df')
1 loops, best of 3: 10.8 s per loop

元のファイルを表示(test.h5、圧縮、test.hdf)

In [13]: !ls -ltr test.h*
-rw-r--r-- 1 jreback users 3471518282 Nov 20 18:20 test.h5
-rw-rw-r-- 1 jreback users  649327780 Nov 20 21:17 test.hdf

注意すべきいくつかの点。

  • インデックスを作成しないと、時間に大きな違いが生じる可能性があります。また、文字列ベースのインデックスがあると、書き込み時間が大幅に悪化する可能性があると私は思います。つまり、検索を非常に高速にするために、常にインデックスを作成する必要があります。

    あなたはあなたのインデックスが何であるか、またはそれがソートされているかどうかを含めませんでした(私はこれが小さな違いを作ると思うだけですが)。

  • 私の例での書き込みペナルティはおよそ2倍です(ただし、インデックス時間を含めると多少大きくなることがわかりました)。したがって、あなたの7秒(私の時間の1/2)、3倍のために私が書いている数字はかなり疑わしいです。かなり高速なディスクアレイを使用しています。フラッシュベースのディスクを使用している場合は、これは可能です。

  • master/v0.13.0(間もなくリリース)、テーブルの書き込み時間を大幅に改善します。

  • データを書き込むときに、chunksizeパラメータをより大きな数に設定してみてください(デフォルトは100000です)。 「比較的」低い数の目的は、一定のメモリ使用量を持つことです。 (たとえば、それよりも大きい場合は、より多くのメモリを使用しますが、理論的にはより速く書き込む必要があります)。

  • テーブルには、固定形式に比べて2つの利点があります。1)クエリの取得、および2)追加可能です。テーブル全体を読み取る場合もどちらも利用しないため、テーブル全体のみを読み取りたい場合は、固定形式をお勧めします。 (私の経験では、テーブルの柔軟性は書き込みペナルティよりもはるかに優れていますが、YMMV)

結論は、タイミングを繰り返すことです(複数のテストを実行するため、ipythonを使用してください)。結果を再現できる場合は、%prunを投稿してください。

更新:

したがって、このサイズのテーブルの推奨される方法は、bloscで圧縮し、PyTables 3.0.0とともにpandas master/0.13.0を使用することです。

9
Jeff