跳转至

h5py — Python 读写 HDF5 科学数据格式的标准库


一句话说明

h5py 让 Python 直接操作 HDF5 文件(.h5/.hdf5),像访问字典一样访问存在文件里的大型数值数组,广泛用于生信、物理、深度学习权重存储。


安装与配置

# pip 安装
pip install h5py                 # 当前版本 3.x

# conda 安装
conda install -c conda-forge h5py

# 验证
python -c "import h5py; print(h5py.__version__)"

# 查看 HDF5 C 库版本
python -c "import h5py; print(h5py.version.hdf5_version)"

核心用法

创建和写入 HDF5

import h5py
import numpy as np

# 创建/打开文件(with 自动关闭)
with h5py.File("experiment.h5", "w") as f:   # w=新建,覆盖已有

    # 直接写入数组(Dataset)
    f.create_dataset(
        "counts",                              # 数据集名
        data = np.random.rand(1000, 500),     # 数据
        compression = "gzip",                 # 压缩方式
        compression_opts = 4,                 # 压缩级别
        chunks = (100, 100),                  # 分块大小
    )

    # 创建子组(类似文件夹)
    grp = f.create_group("metadata")          # 创建子组
    grp.create_dataset("gene_names",          # 基因名列表
        data = np.array(["GeneA", "GeneB"], dtype="S10"))  # 字符串用 bytes

    # 添加属性(小型元数据)
    f.attrs["project"] = "宏基因组研究"       # 文件级属性
    f["counts"].attrs["units"] = "raw_counts" # 数据集级属性

读取 HDF5

with h5py.File("experiment.h5", "r") as f:   # r=只读

    # 查看结构(类似 ls)
    print(list(f.keys()))         # ['counts', 'metadata']

    # 读取数组(懒加载,切片才实际读取)
    counts = f["counts"]          # Dataset 对象
    print(counts.shape)           # (1000, 500)
    print(counts.dtype)           # float64

    # 只读部分(切片)
    subset = counts[0:100, :]     # 读前100行(只读这部分)
    subset = counts[...]          # 读全部(用 ... 代替 :)

    # 读属性
    print(f.attrs["project"])     # 宏基因组研究

实战案例

批量写大矩阵(内存友好)

import h5py
import numpy as np

n_samples, n_features = 100000, 10000  # 10万样本,1万特征

# 先创建空数据集,再分批写入
with h5py.File("large_data.h5", "w") as f:
    dset = f.create_dataset(
        "X",
        shape      = (n_samples, n_features),  # 总大小
        dtype      = "float32",
        chunks     = (1000, n_features),        # 每块1000行
        compression= "lzf",                     # lzf 比 gzip 更快
    )

    # 分批写入,避免内存溢出
    batch = 1000
    for i in range(0, n_samples, batch):
        end = min(i + batch, n_samples)
        dset[i:end, :] = np.random.rand(end-i, n_features).astype("float32")
        print(f"写入进度:{end}/{n_samples}")

遍历文件结构

def print_structure(name, obj):
    """递归打印 HDF5 文件树结构"""
    if isinstance(obj, h5py.Dataset):
        print(f"  [数据] {name}: shape={obj.shape}, dtype={obj.dtype}")
    elif isinstance(obj, h5py.Group):
        print(f"  [组]   {name}/")

with h5py.File("experiment.h5", "r") as f:
    f.visititems(print_structure)    # 遍历所有层级

常见报错与解决

报错原因解决
OSError: Unable to open file文件路径错或已被占用检查路径;用 mode="a" 追加而非 "w"
TypeError: No conversion path写 Python 字符串改用 np.bytes_("str")h5py.string_dtype()
KeyError: '...'键名不存在list(f.keys()) 查看
文件损坏写到一半崩溃with 块确保正常关闭;备份

速查表

操作代码
新建文件h5py.File("f.h5", "w")
追加文件h5py.File("f.h5", "a")
只读文件h5py.File("f.h5", "r")
创建数据集f.create_dataset("name", data=arr)
创建分组f.create_group("grp")
读数据f["name"][...]
读切片f["name"][0:100]
读属性f.attrs["key"]
查看结构list(f.keys())