pandas.DataFrame, Seriesをpickleで保存、読み込み(to_pickle, read_pickle)

pandas.DataFrame, pandas.Seriesオブジェクトをそのままpickleファイルとして保存するにはto_pickle()メソッド、保存したpickleファイルを読み込むにはpd.read_pickle()関数を使います。

pandas.DataFrame.to_pickle — pandas 0.23.4 documentation pandas.read_pickle — pandas 0.23.4 documentation

ここでは以下の内容について説明します。

pickleとは pandasでpickleを使う利点 圧縮処理

pickleとは

pickleはPython標準ライブラリに含まれているモジュールで、Pythonオブジェクトをバイト列に変換(シリアライズ、pickle化)したり、バイト列からPythonオブジェクトに変換(デシリアライズ、非pickle化)したりするために使われる。

12.1. pickle --- Python オブジェクトの直列化 — Python 3.6.6 ドキュメント

便宜上、ここではpickle化されて保存されたファイルをpickleファイルと呼ぶこととします。 なお、上記pickleモジュールのドキュメントにあるように出所不明なpickleファイルは危険な可能性があるので注意。

警告 pickle モジュールはエラーや不正に生成されたデータに対して安全ではありません。信頼できない、あるいは認証されていないソースから受け取ったデータを非 pickle 化してはいけません。 12.1. pickle --- Python オブジェクトの直列化 — Python 3.6.6 ドキュメント

pandasでpickleを使う利点

pandasではpandas.DataFrame, pandas.SeriesオブジェクトをCSVファイルやJSONファイルなどの形式で保存したり読み込んだりするメソッドが用意されています。

pickleファイルはCSVファイルやJSONファイルなどと異なりエディタで中身を確認したり他のアプリケーションで使い回すことはできないが、保存時・読み込み時に特別な設定や処理をすることなくオブジェクトをそのまま読み書きできるという利点があります。 以下のpandas.DataFrameを例とします。日時情報をインデックスとする時系列データで、'list'列にはlist型オブジェクトが格納されています。

import pandas as pd

df = pd.DataFrame({'list': [[0, 0], [0, 1], [1, 0], [1, 1]]},
                  index=pd.date_range('2018-01-01', '2018-01-04', freq='D'))

print(df)
#               list
# 2018-01-01  [0, 0]
# 2018-01-02  [0, 1]
# 2018-01-03  [1, 0]
# 2018-01-04  [1, 1]

print(df.index)
# DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04'], dtype='datetime64[ns]', freq='D')

print(type(df['list'][0]))
# <class 'list'>

CSVファイルで保存・読み込みする場合 CSVで保存して再度読み込む場合、まず、時系列データとしてインデックスを指定するためにread_csv()の引数index_colやparse_datesを指定する必要があります。

df.to_csv('data/dst/pandas_obj.csv')

df_from_csv = pd.read_csv('data/dst/pandas_obj.csv', index_col=0, parse_dates=True)

print(df_from_csv)
#               list
# 2018-01-01  [0, 0]
# 2018-01-02  [0, 1]
# 2018-01-03  [1, 0]
# 2018-01-04  [1, 1]

print(df_from_csv.index)
# DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04'], dtype='datetime64[ns]', freq=None)

さらに、'list'列は文字列として読み込まれるので、例えば組み込み関数eval()を各要素に適用してlist型オブジェクトに変換する必要があります。

print(type(df_from_csv['list'][0]))
# <class 'str'>

df_from_csv['list'] = df_from_csv['list'].apply(eval)

print(df_from_csv)
#               list
# 2018-01-01  [0, 0]
# 2018-01-02  [0, 1]
# 2018-01-03  [1, 0]
# 2018-01-04  [1, 1]

print(type(df_from_csv['list'][0]))
# <class 'list'>

pickleファイルで保存・読み込みする場合 to_pickle(), read_pickle()を使ってpickleファイルとして扱う場合、引数の指定や変換処理をする必要なくオブジェクトを保存でき、そのままの状態で復元できます。

df.to_pickle('data/dst/pandas_obj.pkl')

df_from_pkl = pd.read_pickle('data/dst/pandas_obj.pkl')

print(df_from_pkl)
#               list
# 2018-01-01  [0, 0]
# 2018-01-02  [0, 1]
# 2018-01-03  [1, 0]
# 2018-01-04  [1, 1]

print(df_from_pkl.index)
# DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04'], dtype='datetime64[ns]', freq='D')

print(type(df_from_pkl['list'][0]))
# <class 'list'>

作業を一時中断するためにオブジェクトの状態を保存しておきたい場合などにも、特に何も考える必要がないpickleファイルは便利。

圧縮処理

拡張子を.gz, .bz2, .xz, .zipとして指定すると、自動で圧縮・解凍処理が行われる。

df.to_pickle('data/dst/pandas_obj.zip')

df_from_pkl_zip = pd.read_pickle('data/dst/pandas_obj.zip')

print(df_from_pkl_zip)
#               list
# 2018-01-01  [0, 0]
# 2018-01-02  [0, 1]
# 2018-01-03  [1, 0]
# 2018-01-04  [1, 1]

引数compressionに明示的に形式('gzip', 'bz2', 'xz', 'zip')を指定することも可能。

シェア

関連カテゴリー

Python pandas

pandasでcsvファイルの書き出し・追記(to_csv) pandasでcsv/tsvファイル読み込み(read_csv, read_table) pandas.DataFrame, Seriesを連結するconcat pandas.DataFrameに列や行を追加(assign, appendなど) pandasでstack, unstack, pivotを使ってデータを整形 pandasの要素としてリストを格納し処理 pandasでクリップボードの中身をDataFrameとして取得するread_clipboard Pythonでメソッドチェーンを改行して書く pandas.DataFrame, Seriesの重複した行を抽出・削除 pandas.DataFrameの行と列を入れ替える(転置) pandasの文字列メソッドで置換や空白削除などの処理を行う pandas.DataFrame, SeriesとNumPy配列ndarrayを相互に変換 Python, pandas, seabornでヒートマップを作成 pandasで時系列データの曜日や月、四半期、年ごとの合計や平均を算出 PythonでRESAS APIを使ってデータをダウンロード

Last Updated: 6/26/2019, 10:34:03 PM