来自 pickle.dumps 的较小字符串
Smaller strings from pickle.dumps
我正在想办法让 pickle strings 变小。 pickle 字符串将驻留在脚本中,不能是文件。
下面的例子是一本我不知道内容的小词典。请注意有多少字符串只是 \x。我要压缩的字符串有 93,878 个字符长。我的一个限制是它需要使用 vanilla python 库。我试过使用 gzip 然后从中获取字符串。它节省了大约 2k 个字符。多存点钱就好了。
任何关于使用 pickle 或类似的 vanilla python 包缩小字符串大小的建议都会很棒。
(例子中字符比pickled字符串少,但一般情况下不是这样。)
#Example precomputed data dict.
x = {}
x["T1"] = np.array([[1,2,3,4,5]])
x["T2"] = np.array([[3,4,5,6,7]])
pickle.dumps(x)
# Below is what will end up being used in a script. I would like to use less characters.
pickle_string = b'\x80\x03}q\x00(X\x02\x00\x00\x00T1q\x01cnumpy.core.multiarray\n_reconstruct\nq\x02cnumpy\nndarray\nq\x03K\x00\x85q\x04C\x01bq\x05\x87q\x06Rq\x07(K\x01K\x01K\x05\x86q\x08cnumpy\ndtype\nq\tX\x02\x00\x00\x00i4q\nK\x00K\x01\x87q\x0bRq\x0c(K\x03X\x01\x00\x00\x00<q\rNNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq\x0eb\x89C\x14\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00q\x0ftq\x10bX\x02\x00\x00\x00T2q\x11h\x02h\x03K\x00\x85q\x12h\x05\x87q\x13Rq\x14(K\x01K\x01K\x05\x86q\x15h\x0c\x89C\x14\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00q\x16tq\x17bu.'
precomputed_data = pickle.loads(pickle_string)
继续 kabanus 的想法。
import zlib
s = str(zlib.compress(pickle.dumps(parameters)))
s = s.replace("X", "XX") #searched for XX in the string to begin with.
s = s.replace("\x", "X")
字符数从 93878 减少到 72688。
一个廉价的解决方案是放弃一些 pickle 数据并使用 Numpy 的 tobytes
功能。在我的机器上:
>>> y = {k: v.tobytes() for k, v in x.items()}
>>> len(pickle.dumps(x))
298
>>> len(pickle.dumps(y))
114
成本当然是你不在这里保留 dtype
,但是在你的 pickle 中保存 "int"
仍然便宜得多,特别是如果你的所有数组都具有相同的类型。
然后您可以使用 zlib
做得更好:
>>> import zlib
>>> len(zlib.compress(pickle.dumps(y))
59
压缩 x
仅下降到 207,因此更不理想。
我正在想办法让 pickle strings 变小。 pickle 字符串将驻留在脚本中,不能是文件。
下面的例子是一本我不知道内容的小词典。请注意有多少字符串只是 \x。我要压缩的字符串有 93,878 个字符长。我的一个限制是它需要使用 vanilla python 库。我试过使用 gzip 然后从中获取字符串。它节省了大约 2k 个字符。多存点钱就好了。
任何关于使用 pickle 或类似的 vanilla python 包缩小字符串大小的建议都会很棒。 (例子中字符比pickled字符串少,但一般情况下不是这样。)
#Example precomputed data dict.
x = {}
x["T1"] = np.array([[1,2,3,4,5]])
x["T2"] = np.array([[3,4,5,6,7]])
pickle.dumps(x)
# Below is what will end up being used in a script. I would like to use less characters.
pickle_string = b'\x80\x03}q\x00(X\x02\x00\x00\x00T1q\x01cnumpy.core.multiarray\n_reconstruct\nq\x02cnumpy\nndarray\nq\x03K\x00\x85q\x04C\x01bq\x05\x87q\x06Rq\x07(K\x01K\x01K\x05\x86q\x08cnumpy\ndtype\nq\tX\x02\x00\x00\x00i4q\nK\x00K\x01\x87q\x0bRq\x0c(K\x03X\x01\x00\x00\x00<q\rNNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq\x0eb\x89C\x14\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00q\x0ftq\x10bX\x02\x00\x00\x00T2q\x11h\x02h\x03K\x00\x85q\x12h\x05\x87q\x13Rq\x14(K\x01K\x01K\x05\x86q\x15h\x0c\x89C\x14\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00q\x16tq\x17bu.'
precomputed_data = pickle.loads(pickle_string)
继续 kabanus 的想法。
import zlib
s = str(zlib.compress(pickle.dumps(parameters)))
s = s.replace("X", "XX") #searched for XX in the string to begin with.
s = s.replace("\x", "X")
字符数从 93878 减少到 72688。
一个廉价的解决方案是放弃一些 pickle 数据并使用 Numpy 的 tobytes
功能。在我的机器上:
>>> y = {k: v.tobytes() for k, v in x.items()}
>>> len(pickle.dumps(x))
298
>>> len(pickle.dumps(y))
114
成本当然是你不在这里保留 dtype
,但是在你的 pickle 中保存 "int"
仍然便宜得多,特别是如果你的所有数组都具有相同的类型。
然后您可以使用 zlib
做得更好:
>>> import zlib
>>> len(zlib.compress(pickle.dumps(y))
59
压缩 x
仅下降到 207,因此更不理想。