学習する天然ニューラルネット

主に機械学習に関する覚書や情報の整理。競プロ水色→Kaggle Master→?

pickleより楽にpythonオブジェクトを保存する方法

この記事で言いたいこと

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に書き出したり、読み込んだりしている。

f:id:aotamasaki:20181123120252p:plain

たかが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") #読み出し