h5というファイル形式があることを知る
オライリーから発売されたpythonではじめるアルゴリズムトレードを読み進めていた所、金融の取引データをpandas.DataFrame
からh5
という形式のファイルに出力していました。h5
というファイルは階層的データを扱うためのデータ形式であり、ディレクトリのように階層を経由して値へのアクセスが可能なようです。5というの現在の最新バージョンが5系であるためでそうで、過去にはh4が使用されていたのだそう。
書籍では、h5
のようなバイナリファイルとしてデータをダンプしておくことで、ハードウェアの性能を理論値の最大値まで引き出すことが可能と記載されています。読み込み時にも同様です。なので、インメモリで管理するよりもファイルに書き出しておいた方が良いということでしょうか。
なぜh5形式を採用したのか
ここについてあまり触れられていませんでした。書き込み速度や読み込み速度が他形式よりも高速なのか、メモリ効率が良いのか、アクセスが簡潔なためか分かりませんでした。
自分の知っている限りでは保存形式として.csv
や.pkl
も候補に上がります。また、今回は元データである金融の取引データが.csv
形式のデータであったため、なおのこと.h5
形式のメリットが分かりませんでした。
なので、.csv
と.h5
と.pkl
で読み込み時の速度をメインに比較をしてみました。書き込み時の速度はデータは読み込みケースの方がエンドユーザーは多いという仮説より測定していません。(面倒で(ry)
事前準備
データはpandas.DataFrameで適当なサイズのデータを作成します。numpyで作った適当なデータを格納しています。
def make_mock(rows_size, columns_size, file_name): df = pd.DataFrame( np.arange(rows_size * columns_size).reshape(rows_size, columns_size), columns=[f"col_{n}" for n in range(columns_size)], index=[f"idx_{n}" for n in range(rows_size)], ) df.to_csv(f"{file_name}.csv") df.to_hdf(f"{file_name}.h5", key='df', mode='w') df.to_pickle(f"{file_name}.pkl")
以下は100行5列で作成したpandas.DataFrame
のinfo()
の実行結果です。
<class 'pandas.core.frame.DataFrame'> Index: 100 entries, idx_0 to idx_99 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 col_0 100 non-null int64 1 col_1 100 non-null int64 2 col_2 100 non-null int64 3 col_3 100 non-null int64 4 col_4 100 non-null int64 dtypes: int64(5) memory usage: 4.7+ KB
このpandas.DataFrame
をそれぞれのファイル形式に出力し、読み込み時の速度を計測します。
結果
rows size | columns size | extension | user(ms) | sys(ms) | total(ms) | wall time(ms) | memory usage |
---|---|---|---|---|---|---|---|
100 | 5 | csv | 11.3 | 4 | 11.3 | 13.3 | 4.8KB |
100 | 5 | h5 | 13.5 | 0 | 13.5 | 13.8 | 4.7KB |
100 | 5 | pkl | 11.2 | 3 | 11.2 | 15.7 | 4.7KB |
10000 | 5 | csv | 23.1 | 911 | 24 | 31.5 | 468.9KB |
10000 | 5 | h5 | 21 | 870 | 21.9 | 23.1 | 468.8KB |
10000 | 5 | pkl | 9.37 | 993 | 10.4 | 17 | 468.8KB |
100000 | 5 | csv | 80.3 | 18.3 | 98.5 | 101 | 4.6MB |
100000 | 5 | h5 | 78.5 | 7.89 | 86.4 | 91 | 4.6MB |
100000 | 5 | pkl | 27.4 | 5.11 | 32.5 | 54.6 | 4.6MB |
金融の取引データのような時系列を主とするデータは行数は増えることはあっても、列数が増えることは行数が増える事に比べれば稀だという判断より、行数を100, 10000, 100000で結果を取っています。
行数は適当な数値です。全体的に各形式でそれほど、大きな差はないように見えます。面白いのは.pkl
形式が行数が少ない時は遅かったのですが、行数が増えると他形式よりも倍近く速いです。
また、メモリ使用量(インメモリへpandas.DataFrame
を展開した際の使用量)はほとんど差はありません。違いが出るのは速度だけだと考えて良さそうです。
汎用性も高い.pkl
を使うのが良いんじゃない?という結果になりました。
総括
おそらく、この程度のデータ量ではどれも対して変わらないのでしょう。また、今回は金融の取引という特定ドメインのデータで、pandas
を使うことを前提としていました。
汎用性やユースケースによって適切なデータ形式が変わってくるとは思いますが、.pkl
を無難に選んでおけば良いのではないでしょうか。