Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用h5py压缩现有HDF5数据集,并释放空间,无需复制或使用h5repack_Python_Numpy_Compression_Hdf5_H5py - Fatal编程技术网

Python 使用h5py压缩现有HDF5数据集,并释放空间,无需复制或使用h5repack

Python 使用h5py压缩现有HDF5数据集,并释放空间,无需复制或使用h5repack,python,numpy,compression,hdf5,h5py,Python,Numpy,Compression,Hdf5,H5py,我想使用python HDF5接口h5py对HDF5文件中的某些数据集执行“就地”压缩,并尽可能回收任何空间 根据我观察到的情况,即使将数据集作为numpy数组读入,然后删除HDF5中的原始数据集,然后使用compression='gzip'写回HDF5文件,实际上也不会释放磁盘上的任何空间: #!/usr/bin/env python3 # -*- coding: utf-8 -*- import h5py import numpy as np import os import shutil

我想使用python HDF5接口
h5py
HDF5
文件中的某些数据集执行“就地”压缩,并尽可能回收任何空间

根据我观察到的情况,即使将数据集作为numpy数组读入,然后删除HDF5中的原始数据集,然后使用
compression='gzip'
写回HDF5文件,实际上也不会释放磁盘上的任何空间:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import h5py
import numpy as np
import os
import shutil

data_sngl = np.ones(shape=(100,100,100), dtype=np.float64)*np.pi

# ===== make uncompressed HDF5 for reference

with h5py.File('data_sngl.h5', 'w') as hf:
    hf.create_dataset('data', data=data_sngl, chunks=True)
print('data_sngl.h5 : %0.4f [MB]'%(os.path.getsize('data_sngl.h5')/1000**2))

# ===== make compressed HDF5 for reference

with h5py.File('data_sngl_gz.h5', 'w') as hf:
    hf.create_dataset('data', data=data_sngl, chunks=True, compression='gzip', compression_opts=9, shuffle=True)
print('data_sngl_gz.h5 : %0.4f [MB]'%(os.path.getsize('data_sngl_gz.h5')/1000**2))

# ===== attempt 'in-place' compression

shutil.copy2('data_sngl.h5','data_sngl_bak.h5') ## make a copy

with h5py.File('data_sngl.h5', 'r+') as hf: ## open in read/write mode
    data = np.copy(hf['data'][:])
    del hf['data'] ## deleting dataset!

    ### write with compression opts active
    hf.create_dataset('data', data=data, chunks=True, compression='gzip', compression_opts=9, shuffle=True)

print('data_sngl.h5 : %0.4f [MB] --> after in-place compress'%(os.path.getsize('data_sngl.h5')/1000**2))

# ===== 'repack' the in-place compressed file

os.system('h5repack -i data_sngl.h5 -o data_sngl_repacked.h5')
print('data_sngl_repacked.h5 : %0.4f [MB]'%(os.path.getsize('data_sngl_repacked.h5')/1000**2))

# ===== compress while copying to new file

with h5py.File('data_sngl_bak.h5', 'r') as hf:
    data = np.copy(hf['data'][:])
    with h5py.File('data_sngl_copy.h5', 'w') as hfc:
        hfc.create_dataset('data', data=data, chunks=True, compression='gzip', compression_opts=9, shuffle=True)

print('data_sngl_copy.h5 : %0.4f [MB] --> copy compress'%(os.path.getsize('data_sngl_copy.h5')/1000**2))
未压缩数据的标称大小约为8.7MB。当最初写入新的hdf5/新数据集时,大小要小得多(这是一种理想的压缩情况)

使用“就地”压缩,这意味着数据集作为numpy数组复制到内存中,然后使用
del
删除数据集,然后使用压缩写回numpy数据,文件仍然不会明显变小

如果在该文件上运行了
h5repack
,则可以看到空间缩减

data_sngl.h5 : 8.6793 [MB]
data_sngl_gz.h5 : 0.0505 [MB]
data_sngl.h5 : 7.4656 [MB] --> after in-place compress
data_sngl_repacked.h5 : 0.0441 [MB]
data_sngl_copy.h5 : 0.0505 [MB] --> copy compress
或者,毫不奇怪,如果使用压缩选项使用
h5py
将数据集简单地复制到一个新的HDF5,那么空间缩减也变得可见

data_sngl.h5 : 8.6793 [MB]
data_sngl_gz.h5 : 0.0505 [MB]
data_sngl.h5 : 7.4656 [MB] --> after in-place compress
data_sngl_repacked.h5 : 0.0441 [MB]
data_sngl_copy.h5 : 0.0505 [MB] --> copy compress

有没有办法避免复制到新的HDF5或从外部调用
h5repack
h5py
中是否有一些技巧指示HDF5“重新打包”,允许就地压缩/空间重新分配,而无需有效地将HDF5的完整内容复制到新文件?

我不知道使用任何API回收HDF5文件中空间的“就地”方法。好吧,HDF5C代码没有这个功能。(这就是为什么HDF组提供了
h5repack
)因此,在HDF5 Python包(h5py或PyTables)中都没有repack函数。注意:如果您想要基于Python的重新打包实用程序,PyTables有一个名为
ptrepack
。在重新阅读您的文章后,我意识到如果您只想修改压缩过滤器,就不需要编写任何代码。这可以通过
h5repack
ptrepack
完成。您可以压缩或解压缩,更改压缩级别或算法——无需代码。