forma mais eficiente de pickle uma string
-
22-08-2019 - |
Pergunta
O módulo pickle parece usar caracteres corda escapar quando decapagem; isto torna-se por exemplo ineficiente em matrizes numpy. Considere o seguinte
z = numpy.zeros(1000, numpy.uint8)
len(z.dumps())
len(cPickle.dumps(z.dumps()))
Os comprimentos são caracteres de 1133 e 4249 respectivamente caracteres.
z.dumps () revela algo como "\ x00 \ x00" (zeros reais em string), mas picles parece estar usando a função repr do string (), produzindo "'\ x00 \ x00" (zeros sendo ascii zeros).
i. ( "0" no z.dumps () == False) e ( "0" no cPickle.dumps (z.dumps ()) == True)
Solução
Tente usar uma versão mais recente do protocolo pickle com o parâmetro de protocolo para pickle.dumps()
. O padrão é 0 e é um formato de texto ASCII. Ones superior a 1 (sugiro que você use pickle.HIGHEST_PROTOCOL). formatos de protocolo 1 e 2 (e 3 mas isso é para Py3k) são binários e deve ser mais conservador espaço.
Outras dicas
Solução:
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
z.dumps()
já está em conserva corda ou seja, pode ser unpickled usando pickle.loads ():
>>> z = numpy.zeros(1000, numpy.uint8)
>>> s = z.dumps()
>>> a = pickle.loads(s)
>>> all(a == z)
True
Uma melhora a resposta de vartec, que parece um pouco mais eficiente de memória (uma vez que não forçar tudo em uma string):
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"))