使用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上,因为它可以在项目的其他地方使用,并且我无法通过以下方式对其进行更改我自己。
答案 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以外的其他东西,但:
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.frombuffer
比np.fromstring
更好),并且print(row)
和print(data)
给出了相同的内容。当我在写入过程中添加一个for循环以在文件中添加几个压缩行时,就会出现问题。因此,我很难检索每个完整尺寸的压缩行(带有for line in zFile: ...
)以一次对其进行解压缩。实际上,每个压缩行中的某些元素都被视为\n
,因此不会检索实线(给定zlib.error: Error -5 while decompressing data: incomplete or truncated stream
)