回答:
最も簡単な方法は、次のものを使用してピクルすることto_pickle
です。
df.to_pickle(file_name) # where to save it, usually as a .pkl
次に、次のコマンドを使用してロードし直すことができます。
df = pd.read_pickle(file_name)
注:0.11.1より前のバージョンでsave
ありload
、これを行う唯一の方法でした(現在は推奨されておりto_pickle
、read_pickle
それぞれ推奨されていません)。
もう1つの一般的な選択肢は、大規模なデータセットに対して非常に高速なアクセス時間を提供するHDF5(pytables)を使用することです。
store = HDFStore('store.h5')
store['df'] = df # save it
store['df'] # load it
より高度な戦略については、クックブックで説明しています。
0.13以降は、JSONのより高速な代替手段として、またはPythonオブジェクト/テキストヘビーデータがある場合に相互運用性に優れている可能性があるmsgpackもあります(参照)この質問を)。
すでにいくつかの回答はありますが、Pandas DataFramesをシリアル化するいくつかの方法を試してみた素晴らしい比較が見つかりました:Pandas DataFramesを効率的に保存ます。
彼らは比較します:
彼らの実験では、2つの列を個別にテストして、1,000,000行のDataFrameをシリアル化します。1つはテキストデータ、もう1つは数値です。彼らの免責事項は言う:
以下の内容がデータに一般化されていると信じてはいけません。自分のデータを見て、自分でベンチマークを実行する必要があります
彼らが参照するテストのソースコードはオンラインで入手できます。このコードは直接動作しませんでしたので、私はあなたがここに来ることができますいくつかのマイナーな変更を、作っ:serialize.pyは、 私は以下の結果を得ました:
彼らはまた、テキストデータをカテゴリカルに変換するとデータにすると、シリアル化がはるかに高速になるいます。彼らのテストでは約10倍の速さです(テストコードも参照してください)。
編集:ピクルスのCSVよりも高い時間は、使用されているデータ形式で説明できます。デフォルトでpickle
は、より大きなデータセットを生成する印刷可能なASCII表現を使用します。ただし、グラフからわかるように、新しいバイナリデータ形式(バージョン2、pickle-p2
)を使用したピクルのロード時間ははるかに短くなっています。
その他の参考資料:
numpy.fromfile
、csvファイルの読み取りが最も高速になります。.to_pickle()
(バイナリストレージを使用)と.to_hdf()
(圧縮なしで)を比較しました。目標は速度、HDFのファイルサイズは11倍のPickle、読み込み時間です5x Pickleでした。私のデータは〜7k行x 6列の〜5kファイルで、ほとんどが数値でした
私が正しく理解していれば、既に使用pandas.read_csv()
していますが、スクリプトを編集するたびにファイルをロードする必要がないように開発プロセスをスピードアップしたいと思いますか?私はいくつかの推奨事項を持っています:
pandas.read_csv(..., nrows=1000)
開発を行っている間は、CSVファイルの一部のみをロードして、テーブルの最上位ビットのみをロードできます。
スクリプトを編集してリロードするときにパンダテーブルをメモリに保持するように、インタラクティブセッションにipythonを使用します。
csvをHDF5テーブルに変換する
更新された使用法DataFrame.to_feather()
とpd.read_feather()
、データをR互換のフェザーバイナリ形式で保存する方法(超高速)(私の手ではpandas.to_pickle()
、数値データよりもわずかに速く、文字列データの方がはるかに高速です)。
また、stackoverflowに関するこの回答に興味があるかもしれません。
to_feather
文字列データでうまく機能する理由を知っていますか?私はベンチマークto_pickle
をto_feature
行い、数値データフレームとピクルで約3倍速くなりました。
ピクルスはうまくいきます!
import pandas as pd
df.to_pickle('123.pkl') #to save the dataframe, df to 123.pkl
df1 = pd.read_pickle('123.pkl') #to load 123.pkl back to the dataframe df
.pkl
。@ Andy Haydensの回答で提案されているように、拡張機能を使用することをお勧めします。
フェザー形式のファイルを使用できます。非常に高速です。
df.to_feather('filename.ft')
R
を使用してデータを直接使用できfeather
ます。
Pandas DataFramesには、DataFrameのto_pickle
保存に役立つ関数があります。
import pandas as pd
a = pd.DataFrame({'A':[0,1,0,1,0],'B':[True, True, False, False, False]})
print a
# A B
# 0 0 True
# 1 1 True
# 2 0 False
# 3 1 False
# 4 0 False
a.to_pickle('my_file.pkl')
b = pd.read_pickle('my_file.pkl')
print b
# A B
# 0 0 True
# 1 1 True
# 2 0 False
# 3 1 False
# 4 0 False
すでに述べたように、さまざまなオプションとファイル形式があります(、データフレームを格納するための HDF5、JSON、CSV、寄木細工、SQL)があります。ただし、pickle
は一流の市民ではありません(設定によって異なります)。
pickle
潜在的なセキュリティリスクです。pickleのPythonドキュメントを作成します。警告
pickle
モジュールは、誤ったまたは悪意を持って構築されたデータに対して安全ではありません。信頼できない、または認証されていないソースから受信したデータを抽出しないでください。
設定/使用法によっては両方の制限が適用されませんが、pickle
パンダデータフレームのデフォルトの永続性としてはお勧めしません。
numpyファイルは高速で扱いやすいので、使用することをお勧めします。これは、100万ポイントの1列のデータフレームを保存およびロードするための簡単なベンチマークです。
import numpy as np
import pandas as pd
num_dict = {'voltage': np.random.rand(1000000)}
num_df = pd.DataFrame(num_dict)
ipythonの%%timeit
魔法の関数を使う
%%timeit
with open('num.npy', 'wb') as np_file:
np.save(np_file, num_df)
出力は
100 loops, best of 3: 5.97 ms per loop
データをデータフレームに読み込む
%%timeit
with open('num.npy', 'rb') as np_file:
data = np.load(np_file)
data_df = pd.DataFrame(data)
出力は
100 loops, best of 3: 5.12 ms per loop
悪くない!
python 2を使用してnumpyファイルを保存してから、python 3を使用して開こうとすると問題が発生します(またはその逆)。
https://docs.python.org/3/library/pickle.html
ピクルプロトコル形式:
プロトコルバージョン0は元の「人間が読める」プロトコルであり、以前のバージョンのPythonと下位互換性があります。
プロトコルバージョン1は古いバイナリ形式で、以前のバージョンのPythonとも互換性があります。
プロトコルバージョン2はPython 2.3で導入されました。新しいスタイルのクラスをより効率的にピクルス化します。プロトコル2による改善については、PEP 307を参照してください。
プロトコルバージョン3はPython 3.0で追加されました。バイトオブジェクトを明示的にサポートしており、Python 2.xでunpickleすることはできません。これはデフォルトのプロトコルであり、他のPython 3バージョンとの互換性が必要な場合に推奨されるプロトコルです。
プロトコルバージョン4はPython 3.4で追加されました。非常に大きなオブジェクトのサポート、より多くの種類のオブジェクトのピクル化、および一部のデータ形式の最適化が追加されます。プロトコル4による改善については、PEP 3154を参照してください。
全体的な動きはpyarrow / featherです(pandas / msgpackからの非推奨の警告)。ただし、仕様に一時的な pyarrowでの挑戦があります。pyarrow0.15.1でシリアル化されたデータは、0.16.0で逆シリアル化できませんARROW-7961。シリアル化を使用してredisを使用しているため、バイナリエンコーディングを使用する必要があります。
さまざまなオプションを再テストしました(jupyterノートブックを使用)
import sys, pickle, zlib, warnings, io
class foocls:
def pyarrow(out): return pa.serialize(out).to_buffer().to_pybytes()
def msgpack(out): return out.to_msgpack()
def pickle(out): return pickle.dumps(out)
def feather(out): return out.to_feather(io.BytesIO())
def parquet(out): return out.to_parquet(io.BytesIO())
warnings.filterwarnings("ignore")
for c in foocls.__dict__.values():
sbreak = True
try:
c(out)
print(c.__name__, "before serialization", sys.getsizeof(out))
print(c.__name__, sys.getsizeof(c(out)))
%timeit -n 50 c(out)
print(c.__name__, "zlib", sys.getsizeof(zlib.compress(c(out))))
%timeit -n 50 zlib.compress(c(out))
except TypeError as e:
if "not callable" in str(e): sbreak = False
else: raise
except (ValueError) as e: print(c.__name__, "ERROR", e)
finally:
if sbreak: print("=+=" * 30)
warnings.filterwarnings("default")
データフレームの次の結果(out
jupyter変数内)
pyarrow before serialization 533366
pyarrow 120805
1.03 ms ± 43.9 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
pyarrow zlib 20517
2.78 ms ± 81.8 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
msgpack before serialization 533366
msgpack 109039
1.74 ms ± 72.8 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
msgpack zlib 16639
3.05 ms ± 71.7 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
pickle before serialization 533366
pickle 142121
733 µs ± 38.3 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
pickle zlib 29477
3.81 ms ± 60.4 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
feather ERROR feather does not support serializing a non-default index for the index; you can .reset_index() to make the index into column(s)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
parquet ERROR Nested column branch had multiple children: struct<x: double, y: double>
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
羽毛と寄木細工がデータフレームで機能しません。pyarrowを使い続けます。しかし、私は漬物で補います(圧縮なし)。キャッシュストアへの書き込み時、pyarrowおよびpickleのシリアル化されたフォーム。pyarrowの逆シリアル化が失敗した場合、キャッシュのフォールバックからピクルに読み取ります。
形式はユースケースによって異なります
パンダのファイル形式の比較はこのビデオにあります。