manera más eficiente para el decapado de una cadena
-
22-08-2019 - |
Pregunta
El módulo pickle parece utilizar caracteres de escape de cadena cuando decapado; esto se convierte por ejemplo ineficiente en matrices numpy. Considere lo siguiente
z = numpy.zeros(1000, numpy.uint8)
len(z.dumps())
len(cPickle.dumps(z.dumps()))
Las longitudes son 1133 caracteres y caracteres 4249 respectivamente.
z.dumps () revela algo así como "\ x00 \ x00" (ceros reales en cadena), pero la salmuera parece estar usando la función de la cadena de repr (), produciendo " '\ x00 \ x00'" (ceros siendo ascii ceros).
es decir. ( "0" en z.dumps () == false) y ( "0" en cPickle.dumps (z.dumps ()) == true)
Solución
Trate de usar una versión posterior del protocolo pickle con el parámetro de protocolo para pickle.dumps()
. El valor por defecto es 0 y es un formato de texto ASCII. Los mayores de 1 (I sugieren que utilice pickle.HIGHEST_PROTOCOL). formatos de protocolo 1 y 2 (y 3, pero eso es para py3k) son binarios y deben ser más espacio conservador.
Otros consejos
Solución:
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()
ya se decapa cadena es decir, se puede unpickled usando pickle.loads ():
>>> z = numpy.zeros(1000, numpy.uint8)
>>> s = z.dumps()
>>> a = pickle.loads(s)
>>> all(a == z)
True
Una mejora de la respuesta de VarTec, que parece un poco más eficiente de la memoria (ya que no obliga a todo en una cadena):
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"))