我有一个pandas数据帧(pd.DataFrame),结构如下:
In [175]: df.dtypes.value_counts()
Out[175]:
int64 876
float64 206
object 76
bool 9
dtype: int64
In [176]: df.shape
Out[176]: (9764, 1167)
我已通过以下三种方式将数据存储到磁盘:
In [170]: df.to_csv('df.csv')
In [171]: df.to_pickle('df_v1.pkl')
In [172]: import pickle
In [173]: with open('df_v2.pkl', 'wb') as handle:
.....: pickle.dump(df, handle)
磁盘上文件的大小如下:
df.csv: 26.4 MB
df_v1.pkl: 90.5 MB
df_v2.pkl: 340.4 MB
csv
可以理解为小 - 它没有保存的熊猫开销(也就是说,它不需要保存数据帧dtypes等)
我不明白为什么来自两种不同pickle
方法的pickle
s的大小差别如此之大!另外,一个优先于另一个吗?那么向后兼容性呢?
答案 0 :(得分:2)
查看to_pickle
的{{3}},pandas在挑选DataFrame时选择了最有效的协议。通过source code,pickle.dump
使用ASCII协议,就文件大小而言,这是最低效的协议。这样做是为了确保兼容性,并使其更容易恢复,因为ASCII协议是人类可读的。
代码的等效代码是将pickle.dump
行改为:
pickle.dump(df, handle, protocol=pickle.HIGHEST_PROTOCOL)
我只使用to_pickle
方法,因为它会产生更干净的代码。除非您需要与旧版本的Python兼容,否则不应存在任何向后兼容性问题; Python 2.3中引入了更高效的pickle
协议。
另外需要注意的是,大熊猫使用default来提高性能,而不是pickle
本身。这不应该影响文件大小,但它是两者之间的另一个潜在差异。一般情况下,您应尽可能使用cPickle
,并且只有在pickle
不支持您要执行的操作时才使用cPickle
。