7

b1.pklという名前のファイルにピクルスオブジェクトがあります。

$ 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()

このコードが作成するファイルは、2倍以上の大きさです。

$ 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

新しいファイルが元のファイルよりもはるかに大きい理由を誰かが説明できますか?まったく同じ構造が含まれている必要があります。

4

3 に答える 3

12

元のピクルスが他のプロトコルを使用していた可能性があります。たとえばprotocol=2、2番目の引数としてキーワード引数として指定して、pickle.dumpもう一度テストしてみてください。バイナリピクルスはサイズがはるかに小さいはずです。

于 2012-10-11T23:06:39.350 に答える
5

ほとんどの場合、オリジナルb1.pklはより効率的なプロトコルモード(1または2)を使用して選択されています。したがって、ファイルは最初は小さくなります。

cPickleを使用してロードすると、ファイルからプロトコルが自動的に検出されます。しかし、デフォルトの引数を使用して再度ダンプすると、はるかに大きいプロトコル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
于 2012-10-11T23:09:25.443 に答える
3

pkl.dump(x、fout、2)は、おそらく同じファイルサイズになります。プロトコルバージョンを指定しないと、pickleは古いバージョン0を使用します。

于 2012-10-11T23:06:28.273 に答える