酸洗模块似乎在酸洗时使用字符串转义字符;这变得效率低下,例如在numpy数组上。请考虑以下
z = numpy.zeros(1000, numpy.uint8)
len(z.dumps())
len(cPickle.dumps(z.dumps()))
长度分别为1133个字符和4249个字符。
z.dumps()显示类似“\ x00 \ x00”(字符串中的实际零),但pickle似乎使用字符串的repr()函数,产生“'\ x00 \ x00'”(零是ascii零)。
即。 (z.dumps()中的“0”== False)和(cPickle.dumps中的“0”(z.dumps())== True)
答案 0 :(得分:23)
尝试使用更新版本的pickle协议和pickle.dumps()
的协议参数。默认值为0,是ASCII文本格式。一个大于1(我建议你使用pickle.HIGHEST_PROTOCOL)。协议格式1和2(和3,但py3k的格式)是二进制的,应该更加空间保守。
答案 1 :(得分:8)
解决方案:
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
答案 2 :(得分:3)
z.dumps()
已经是pickle字符串,也就是说,它可以使用pickle.loads()进行打开:
>>> z = numpy.zeros(1000, numpy.uint8)
>>> s = z.dumps()
>>> a = pickle.loads(s)
>>> all(a == z)
True
答案 3 :(得分:1)
对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"))