effizienter Weg, um einen String beizen
-
22-08-2019 - |
Frage
Die Beize Modul scheint String Escape-Zeichen zu verwenden, wenn Beizen; Dies wird ineffizient z.B. auf numpy Arrays. Betrachten Sie das folgende
z = numpy.zeros(1000, numpy.uint8)
len(z.dumps())
len(cPickle.dumps(z.dumps()))
Die Längen sind 1133 Zeichen und 4249 Zeichen sind.
z.dumps () zeigt, so etwas wie "\ x00 \ x00" (Ist-Nullen in string), aber Gurke scheint die Zeichenfolge des repr () Funktion zu verwenden, wodurch man "'\ x00 \ x00" (Nullen sein ascii Nullen).
d. ( "0" in z.dumps () == False) und ( "0" in cPickle.dumps (z.dumps ()) == True)
Lösung
Versuchen Sie, eine neuere Version des Pickle Protokoll mit dem Protokoll-Parameter verwenden zu pickle.dumps()
. Der Standardwert ist 0 und ist ein ASCII-Textformat. Ones größer als 1 (Ich schlage vor, Sie verwenden pickle.HIGHEST_PROTOCOL). Protokollformate 1 und 2 (und 3, aber das ist für py3k) sind binär und sollen mehr Raum konservativ sein.
Andere Tipps
Lösung:
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()
ist bereits eingelegte Zeichenkette das heißt, es kann sein ungebeizte mit pickle.loads ():
>>> z = numpy.zeros(1000, numpy.uint8)
>>> s = z.dumps()
>>> a = pickle.loads(s)
>>> all(a == z)
True
Eine Verbesserung vartec Antwort, die ein bisschen mehr Speicher effizienter scheint (da es nicht alles in einen String zwingen wird):
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"))