更有效的方法来挑选一个字符串

时间:2009-03-30 01:48:22

标签: python numpy pickle space-efficiency

酸洗模块似乎在酸洗时使用字符串转义字符;这变得效率低下,例如在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)

4 个答案:

答案 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"))