为什么pd.DataFrame pickle大小在df.to_pickle和原生Python pickle之间变化很大?

时间:2016-03-31 17:03:39

标签: python pandas dataframe pickle

我有一个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的大小差别如此之大!另外,一个优先于另一个吗?那么向后兼容性呢?

1 个答案:

答案 0 :(得分:2)

查看to_pickle的{​​{3}},pandas在挑选DataFrame时选择了最有效的协议。通过source codepickle.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