طريقة أكثر كفاءة لمخلل سلسلة
-
22-08-2019 - |
سؤال
وحدة المخلل ويبدو أن استخدام أحرف الهروب السلسلة عند التخليل. هذا يصبح مثل عدم كفاءة على صفائف نمباي. مراعاة ما يلي
z = numpy.zeros(1000, numpy.uint8)
len(z.dumps())
len(cPickle.dumps(z.dumps()))
وأطوال هي 1133 حرفا والأحرف 4249 على التوالي.
وz.dumps () يكشف عن شيء من هذا القبيل "\ x00 \ x00" (الأصفار الفعلية في سلسلة)، ولكن المخلل ويبدو أن استخدام وظيفة سلسلة من repr ()، مما أسفر عن " '\ x00 \ x00" (الأصفار يجري أسكي الأصفار).
وأي بمعنى. ( "0" في z.dumps () == كاذبة) و ( "0" في cPickle.dumps (z.dumps ()) == صحيح)
المحلول
وحاول استخدام إصدار أحدث من بروتوكول المخلل مع المعلمة بروتوكول لpickle.dumps()
. الافتراضي هو 0 و هو نص على شكل ASCII. منها أكبر من 1 (أقترح عليك استخدام pickle.HIGHEST_PROTOCOL). صيغ بروتوكول 1 و 2 (و 3 ولكن هذا لpy3k) هي ثنائية وينبغي أن تكون أكثر تحفظا الفضاء.
نصائح أخرى
والحل:
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()
سلسلة بمعنى أنه يمكن unpickled باستخدام pickle.loads ():
>>> z = numpy.zeros(1000, numpy.uint8)
>>> s = z.dumps()
>>> a = pickle.loads(s)
>>> all(a == z)
True
وهذا التحسن إلى الإجابة 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"))