zlib使用python压缩/解压缩文件

时间:2020-04-11 17:48:06

标签: python python-3.x zlib

使用zlib,我希望能够压缩numpy数组并将其写入文件中,然后能够读回它们。我做了以下

with open(outputFile, 'wb') as zFile:
    for row in array:
        compressed = zlib.compress(row, compressionLevel)
        zFile.write(compressed)
with open(os.path.join(path, fileName), 'rb') as zFile:
    for line in zFile:
        decompressed = zlib.decompress(line)
        data.append(decompressed)
data = np.array(data)

写入过程在填充文件时起作用,如果我用compressionLevel = 0写入更简单的数据,就可以了。但是我无法使阅读过程正常进行。我尝试这样做zlib.compress(row.tobytes() + '\n'.encode(), compressionLevel),以便可以读取适当的行,但是数据中的某些元素似乎被解释为\n,因此它不读取实际的行。

我也尝试在while循环中读取文件zFile.read(bufferSize),并在没有更多要读取的内容时中断循环,但是先前压缩的每个元素的大小都不同(由于每行的性能不同)所以我无法提前知道缓冲区的大小。

编辑:关于答案,看来np.savez_compress更合适,但目前,我仍停留在zlib上,因为它可以在项目的其他地方使用,并且我无法通过以下方式对其进行更改我自己。

3 个答案:

答案 0 :(得分:1)

使用内置的numpy.savez_compressed吗? 来自numpy docs

>>> test_vector = np.random.rand(4)
>>> np.savez_compressed('/tmp/123', a=test_array, b=test_vector)
>>> loaded = np.load('/tmp/123.npz')
>>> print(np.array_equal(test_array, loaded['a']))
True
>>> print(np.array_equal(test_vector, loaded['b']))
True

答案 1 :(得分:1)

压缩numpy数组的最佳选择之一是使用np.savez_compressed。 这样会更好,但会更慢。我认为您的压缩代码不正确

import numpy as np
import zlib
input_arr = np.arange(100)
dtype = input_arr.dtype
compressed_arr = zlib.compress(input_arr, 2)
decompressed_arr = np.fromstring(zlib.decompress(compressed_arr), dtype)

您还可以使用性能更好的blosc

答案 2 :(得分:0)

因此,总而言之,我目前不能使用zlib以外的其他东西,但:

  • 我可以完全压缩/解压缩(唯一的)numpy数组,并将其写入文件/从文件读取,如下所示:
row = array[0,:]
with open(outputFile, 'wb') as zFile:
    print(row)
    compressed = zlib.compress(row, compressionLevel)
    zFile.write(compressed)
with open(os.path.join(path, fileName), 'rb') as zFile:
    decompressed = zlib.decompress(zFile.read())
    data = np.frombuffer(decompressed, dtype=np.float))
    print(data)
  • 我添加了np.frombuffer,正如sagarwal指出的(实际上np.frombuffernp.fromstring更好),并且print(row)print(data)给出了相同的内容。当我在写入过程中添加一个for循环以在文件中添加几个压缩行时,就会出现问题。因此,我很难检索每个完整尺寸的压缩行(带有for line in zFile: ...)以一次对其进行解压缩。实际上,每个压缩行中的某些元素都被视为\n,因此不会检索实线(给定zlib.error: Error -5 while decompressing data: incomplete or truncated stream