2009-03-30 20 views
9

pickleモジュールはpickling時に文字列エスケープ文字を使用するようです。これは非効率的になる。 numpy配列で。次を考慮してくださいより効率的な方法で文字列を拾う

長さはそれぞれ1133文字と4249文字です。

z.dumps()は "\ x00 \ x00"(文字列の実際のゼロ)を示しますが、pickleは文字列のrepr()関数を使っているようです。 "\ x00 \ x00"アスキーゼロ)。

すなわち(z.dumpsで "0"()==偽)と(cPickle.dumpsで "0"(z.dumps())== TRUE)

+0

投稿に特定の質問を追加する必要があります再。 –

+0

Python文字列またはnumpyのバイト配列をシリアル化するにはどうしますか? – jfs

+1

はlen(cPickle.dumps(z)) – vartec

答えて

23

の以降のバージョンを使用してみてくださいプロトコルパラメーターをpickle.dumps()に設定してください。デフォルトは0で、ASCIIテキスト形式です。 1より大きい(pickle.HIGHEST_PROTOCOLを使用することをお勧めします)。プロトコルフォーマット1と2(そして3つはpy3kのものです)はバイナリであり、より控えめな空間でなければなりません。

+0

[Python 3はデフォルトでプロトコル3を使用します。](https://docs.python.org/3/library/pickle.html#data-stream-format) –

8

ソリューション:

import zlib, cPickle 

def zdumps(obj): 
    return zlib.compress(cPickle.dumps(obj,cPickle.HIGHEST_PROTOCOL),9) 

def zloads(zstr): 
    return cPickle.loads(zlib.decompress(zstr)) 

>>> len(zdumps(z)) 
128 
+0

ここにあります件名:http://tinyurl.com/3ymhaj5。基本的に、ディスクにシリアライズしている場合は、openではなくgzip.open()を実行するだけです。 –

+0

@ slack3rそのリンクは死んでいます。 – kynan

+0

'ascii'コーデックは文字 'u' \ xda 'を位置1にエンコードできません:序数は範囲外です(128) –

1

(それは文字列にすべてを強制するものではありませんので)少しより多くのメモリ効率的なようだvartecの答えへの改善:

def pickle(fname, obj): 
    import cPickle, gzip 
    cPickle.dump(obj=obj, file=gzip.open(fname, "wb", compresslevel=3), protocol=2) 

def unpickle(fname): 
    import cPickle, gzip 
    return cPickle.load(gzip.open(fname, "rb")) 
+0

-1(1)プロトコル番号をハードコードしないで、 '-1'または' HIGHEST_PROTOCOL' 。 (2)その後の圧縮はADD-ONであり、彼の質問とは無関係である。 (3)解凍時に 'compresslevel'を指定するのは無意味です。ファイルを圧縮解除するのに必要な情報は、圧縮ファイルのヘッダーに格納されます。そうでなければ、どの圧縮レベルが使用されていたかわからない場合、どのようにファイルを解凍できますか? –

+0

(1)その後、py2コードはpy3オブジェクトを読み込みません。 (2)ヘッダーに「圧縮を使っていたvartecの答えが改善されました」と書かれている - memの使用量は少ないと思うけど、誤った印象かもしれない...(3)fixed – gatoatigrado

3

z.dumps()がすでに漬けされつまり、pickle.loads()を使用してアンピケッとすることができます。

>>> z = numpy.zeros(1000, numpy.uint8) 
>>> s = z.dumps() 
>>> a = pickle.loads(s) 
>>> all(a == z) 
True 
関連する問題