压缩序列化Python数据最节省空间的方法是什么?

时间:2019-09-18 00:14:35

标签: python serialization compression pickle

来自the Python documentation

  

默认情况下,泡菜数据格式使用相对紧凑的二进制表示形式。如果需要最佳的大小特征,则可以有效地压缩腌制的数据。

在要运行几个小时的过程结束时,我将序列化数GB的数据,我希望结果在磁盘上尽可能小。但是,Python offers several different ways to compress data

是否有其中一种对腌制文件特别有效?我正在腌制的数据主要由嵌套的字典和字符串组成,因此如果有更有效的压缩方式,例如JSON,也可以。

压缩和解压缩的时间并不重要,但是此过程生成数据所花费的时间使反复试验变得不便。

2 个答案:

答案 0 :(得分:2)

我已经使用Pickled对象进行了一些测试,lzma的压缩效果最佳。

但是您的结果可能会因数据而异,建议您使用自己的一些样本数据对其进行测试。

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        9/17/2019  10:05 PM       23869925 no_compression.pickle
-a----        9/17/2019  10:06 PM        6050027 gzip_test.gz
-a----        9/17/2019  10:06 PM        3083128 bz2_test.pbz2
-a----        9/17/2019  10:07 PM        1295013 brotli_test.bt
-a----        9/17/2019  10:06 PM        1077136 lmza_test.xz

使用的测试文件(您需要pip install brotli或删除该算法):

import bz2
import gzip
import lzma
import pickle

import brotli


class SomeObject():

    a = 'some data'
    b = 123
    c = 'more data'

    def __init__(self, i):
        self.i = i


data = [SomeObject(i) for i in range(1, 1000000)]

with open('no_compression.pickle', 'wb') as f:
    pickle.dump(data, f)

with gzip.open("gzip_test.gz", "wb") as f:
    pickle.dump(data, f)

with bz2.BZ2File('bz2_test.pbz2', 'wb') as f:
    pickle.dump(data, f)

with lzma.open("lmza_test.xz", "wb") as f:
    pickle.dump(data, f)

with open('no_compression.pickle', 'rb') as f:
    pdata = f.read()
    with open('brotli_test.bt', 'wb') as b:
        b.write(brotli.compress(pdata))

答案 1 :(得分:1)

我采用“有效压缩腌制数据”来表示通用压缩器趋向于运行良好。但是Pickle是一种协议,本身不是一种格式。通过在自定义类上实现__reduce__方法,可以使pickle发出压缩的字节串。尝试进一步压缩这些文件将无法正常工作。

在标准库压缩器中,LZMA通常会在典型数据流上为您提供最佳比率,但它也是最慢的比率。使用ZPAQ,您可能甚至可以做得更好(例如通过pyzpaq),但这甚至更慢。