我在一个名为b1.pkl的文件中有一个pickle对象:
$ ls -l b*
-rw-r--r-- 1 fireball staff 64743950 Oct 11 15:32 b1.pkl
然后我运行以下python代码来加载对象并将其转储到新文件:
import numpy as np
import cPickle as pkl
fin = open('b1.pkl', 'r')
fout = open('b2.pkl', 'w')
x = pkl.load(fin)
pkl.dump(x, fout)
fin.close()
fout.close()
此代码创建的文件大于两倍:
$ ls -l b*
-rw-r--r-- 1 fireball staff 64743950 Oct 11 15:32 b1.pkl
-rw-r--r-- 1 fireball staff 191763914 Oct 11 15:47 b2.pkl
有谁可以解释为什么新文件比原始文件大得多?它应该包含完全相同的结构。
答案 0 :(得分:10)
原来的泡菜可能会使用其他一些协议。例如,尝试将protocol=2
指定为第二个pickle.dump
的关键字参数,然后再次测试。二元泡菜的尺寸要小得多。
答案 1 :(得分:4)
最有可能的原始b1.pkl
使用更有效的协议模式(1或2)进行了挑选。所以你的文件开始变小了。
使用cPickle加载时,它会自动从文件中检测到您的协议。但是当你再次使用默认args将其转储出来时,它将使用更大的协议0。它是为了便携性/兼容性。您需要明确请求二进制协议。
import numpy as np
import cPickle
# random data
s = {}
for i in xrange(5000):
s[i] = np.random.randn(5,5)
# pickle it out the first time with binary protocol
with open('data.pkl', 'wb') as f:
cPickle.dump(s, f, 2)
# read it back in and pickle it out with default args
with open('data.pkl', 'rb') as f:
with open('data2.pkl', 'wb') as o:
s = cPickle.load(f)
cPickle.dump(s, o)
$ ls -l
1174109 Oct 11 16:05 data.pkl
3243157 Oct 11 16:08 data2.pkl
答案 2 :(得分:3)
pkl.dump(x,fout,2)可能会导致相同的文件大小。 不指定协议版本将使pickle使用旧版本0。