python - 使用 h5py 压缩现有 HDF5 数据集并释放空间,无需复制或使用 h5repack
问题描述
HDF5
我想使用 python HDF5 接口对文件中的某些数据集执行“就地”压缩h5py
并回收任何可能的空间。
根据我的观察,即使将数据集作为 numpy 数组读取,然后删除 HDF5 中的原始数据集,然后使用写回 HDF5 文件compression='gzip'
,实际上也不会释放磁盘上的任何空间:
#!/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
在该文件上运行,则空间减少变得可见。
或者,不出所料,如果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 的完整内容复制到新文件中?
解决方案
推荐阅读
- android - HUAWEI P20 Lite相机2拍照时出错
- python - 有没有更有效的方法将文件大量导入 PostgreSQL?
- java - 使用 java 使用 selenium webdriver 查看页面源的屏幕截图
- r - 数据框添加基于条件计数频率的列
- python - 将复杂格式的文本解析为python数据表
- android - 如何不丢失连接BLE
- node.js - 如何在 Node 中的 Mongoose 上触发套接字事件?
- java - Websphere jdbc连接不可用
- python - 在 jupyter notebook 中以离线模式使用 plotly(使用 nbcovert --execute)打开 IDE(vscode)
- php - PHP 7.2 更新:标题中的 DropDown 警告声明