modo più efficiente decapare una stringa
-
22-08-2019 - |
Domanda
Il modulo pickle sembra utilizzare caratteri di stringa di escape quando decapaggio; questo diventa esempio inefficiente su array numpy. Si consideri il seguente
z = numpy.zeros(1000, numpy.uint8)
len(z.dumps())
len(cPickle.dumps(z.dumps()))
Le lunghezze sono rispettivamente 1133 e 4249 caratteri caratteri.
z.dumps () rivela qualcosa del tipo "\ x00 \ x00" (zeri reali in stringa), ma salamoia sembra essere utilizzando la funzione della stringa repr (), dà il " '\ x00 \ x00'" (zeri essendo ascii zeri).
vale a dire. ( "0" in z.dumps () == false) e ( "0" in cPickle.dumps (z.dumps ()) == true)
Soluzione
Provare a usare una versione successiva del protocollo pickle con il parametro protocollo pickle.dumps()
. Il valore di default è 0 ed è un formato di testo ASCII. Quelli superiori a 1 (vi suggerisco di utilizzare pickle.HIGHEST_PROTOCOL). formati Protocollo 1 e 2 (e 3, ma questo è py3k) sono binari e dovrebbero essere più spazio conservatore.
Altri suggerimenti
Soluzione:
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()
è già serializzato stringa cioè, può essere poterlo più deserializzare utilizzando pickle.loads ():
>>> z = numpy.zeros(1000, numpy.uint8)
>>> s = z.dumps()
>>> a = pickle.loads(s)
>>> all(a == z)
True
Un miglioramento alla risposta di Vartec, che sembra un po 'più efficiente della memoria (dal momento che non forza tutto in una stringa):
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"))