この記事で言いたいこと
import pickleしてwith openをいちいち書くのめんどくさくない?。pandas.to_pickleやpandas.read_pickleを使えば楽。DataFrame以外のものも保存できる。
はじめに
pythonは辞書やリスト、もしくはクラスから生成したインスタンス等を保存する機能を提供している。
pickle --- Python オブジェクトの直列化 — Python 3.7.3rc1 ドキュメント
現在(2018/11/23)、googleで検索するとたくさんの記事が出てくる。しかしどれもpickleのドキュメントに準拠したものになっていて、pickleをimportし、with openでpickleに書き出したり、読み込んだりしている。
たかが2,3行かもしれないがこれを何回も書くのは意外とめんどくさい。pandasを使えばもっと楽に任意のpythonオブジェクトを保存したり読み出したりできる。以下コードを交えて、紹介する。
pandasというと、DataFrameを扱うイメージが強い。 しかし、to_pickleのdocstringを見てみると、ちゃんと任意のpythonオブジェクトを引数にできると書いてある。
Signature: pd.to_pickle(obj, path, compression='infer', protocol=4) Docstring: Pickle (serialize) object to file. Parameters ---------- obj : any object Any python object. path : str File path where the pickled object will be stored. 以下略
データの用意
適当に階差が4の数列を作り、これを保存するpythonオブジェクトとする。
arr = [a for a in range(0,50,4)] arr
[0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48]
pickleをimportしてwith openで書き込んだり読み込んだりするやり方
よくやられるやり方で、保存し読み出してみる
import pickle with open("arr.pkl", "wb") as f: pickle.dump(arr, f) #保存
with open("arr.pkl", "rb") as f: hoge = pickle.load(f) #読み出し hoge
[0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48]
del hoge
! rm arr.pkl
pandasを使ったやりかた
import pandas as pd pd.to_pickle(arr, "arr.pkl")#保存
hoge = pd.read_pickle("arr.pkl") #読み出し hoge
[0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48]
こちらの方が、1行で保存も読み出しもできる。そのうえ入力する単語数も少ないので、とにかく楽なのである。pickleをimportする必要すらない。
まとめ
- pythonオプジェクトを保存するときはpandasを使うと楽
- pandas.to_pickleで保存、pandas.read_pickleで読み出し
追記 こんな記事書いてあれなんですけど、joblibの方が容量節約になるので最近はそればっかり使ってます
import joblib joblib.dump(arr, "arr.jb", compress=3) #いい感じに圧縮して保存してくれます hoge=joblib.load("arr.jb") #読み出し