上司「え?このテーブル、Pickleで保存してるの?」
PythonのpandasやDask、VAEXなどでデータ分析をしていると
保存するデータが大きくなってしまいディスク容量がひっ迫したり
読み込み、書き込みに時間がかかって作業が進まなくなってしまうことがあります。
そういう時には保存するファイルフォーマットを変えてみるといいかもしれません。
Pickleの話
Pickleを分析対象のデータのメインの保存形式にすることはおすすめしません。
なぜなら、Pickleは長期保存に適さないからです。
PickleはPythonに標準装備されているバイナリフォーマットの保存方法です。
あらゆるPythonモジュールをそのままバイナリ化して保存することができるので非常に扱いやすく、
バイナリフォーマットなのでIOもCSVよりも圧倒的に早くなります。
Pickleを使う際のデメリットは以下の2つです。
- Pythonのバージョン、ライブラリのバージョン間の互換性がない。
- Python以外の言語、ツールでは扱えない。
つまり、少しでも使用環境が変われば使えなくなってしまいます。
Celeryなどを使ったデータ処理の中間データを使う分にはPickleでいいと思いますが、
長期的に使う場合やチームメンバーに共有したい場合はPickleの使用は避けるべきだと思います。
HDF5
HDFはHierarchical Data Formatの略で階層的にデータをあつかうフォーマットです。
複数のExcelファイルをまとめて一つのHDF5ファイルにするなんてこともできます。
HDFViewというJavaベースのGUIもあるらしいです。使ったことはありません…
h5pyで大体の構造はわかるので今のところ事足りています。
バイナリフォーマットということもあり読み書きの速さはCSVと比べて10~20倍早いです。
Pythonでビッグデータの分析をするためのライブラリにVAEXがありますが
VAEXではほとんどの使用例がHDF5で書かれており、HDF5でなければ本来のパフォーマンスを発揮できません。
(VAEXのHDF5の形式とpandas, DaskのHDF5の保存形式は異なるので注意が必要です。)
APIもCSVとほぼ同じです。
Daskでも使う場合はformat="table"
を忘れないようにしましょう。
# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_hdf.html
df = pd.DataFrame([[1, 1.0, 'a']], columns=['x', 'y', 'z'])
df.to_hdf('./store.h5', 'data', format="table") # Dask用にformatを追加
reread = pd.read_hdf('./store.h5')
Apache Parquet
使ったことはありませんがHDF5との比較でよく見かけます。
圧縮ファイルサイズが小さく、読み書きの速度は若干HDF5より遅いですがCSVよりは圧倒的に早いです。
AWS AthenaなどのAWSのサービスとの互換性が高く使えるという点もHDF5より優れています。
こちらも同様のAPIで使えます。
# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_parquet.html
df = pd.DataFrame(data={'col1': [1, 2], 'col2': [3, 4]})
df.to_parquet('df.parquet.gzip',
compression='gzip')
pd.read_parquet('df.parquet.gzip')
結論:HDF5かParquetを環境や条件に合わせて使いましょう。
AWSなどの解析環境と使えるストレージによってHDF5、Parquetを使い分けるといいです。
データの行数、列数によってまた優劣が変わるらしいのでその辺も今後調べていきたいです。
記事を書いてからこちらの記事を見つけました。
圧倒的に詳しくてわかりやすい…
https://qiita.com/simonritchie/items/a1a18a36de3c658cf816