mcpField
H
h5py

h5py

github.com/tondevrel数据与数据库2450 次安装38 周前更新
代码仓库

关于 h5py

h5py 是连接 NumPy 与 HDF5 的 Python 库,用于组织和访问大型数值数据集。它适合需要分层存储、元数据及按需读取磁盘数据的科学与数据处理工作。

主要功能

  1. 01分层管理组与数据集
  2. 02支持 NumPy 式切片
  3. 03为对象附加元数据属性
  4. 04分块与压缩存储
  5. 05创建可调整大小的数据集

适用场景

  1. 01存储大于可用内存的数组
  2. 02组织科学数据及其元数据
  3. 03读取大型文件中的选定区域
  4. 04随时间追加模拟数据

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tondevrel/scientific-agent-skills --skill h5py

安装后在 Claude Code 中输入/h5py确认已加载。

详细介绍

h5py - 分层数据存储

h5py 在 NumPy 与 HDF5 之间提供了无缝桥接。它允许你将数据组织到组(类似文件夹)和数据集(类似 NumPy 数组)中,并为每个对象附加丰富的元数据(属性)。

适用场景

  • 存储远大于计算机 RAM 的数据集。
  • 将复杂的科学数据组织成分层的“文件夹式”结构。
  • 存储支持高速随机访问的数值数组(NumPy)。
  • 将元数据(单位、实验日期、参数)直接附加到数据上。
  • 在不同语言(C、C++、Fortran、Java、MATLAB)之间共享数据,因为 HDF5 是跨平台标准。
  • 分块读取/写入大型数据集,以优化 I/O 性能。

参考文档

官方文档:https://docs.h5py.org/
HDF Group:https://www.hdfgroup.org/
搜索模式:h5py.File、create_dataset、h5py.Group、chunks=True、compression="gzip"

核心原则

层级结构

HDF5 文件包含两种主要对象:

  • 数据集:多维数据数组(类似 NumPy)。
  • 组:可以容纳数据集或其他组的容器结构(类似目录)。
切片

h5py 数据集支持标准的 NumPy 切片。对数据集进行切片时,只会从磁盘读取指定切片,从而减少内存占用。

属性

每个组和数据集都可以包含用于存储元数据的属性(键值对)。

快速参考

安装
pip install h5py
标准导入
import h5py
import numpy as np
基本模式 - 写入和读取
import h5py
import numpy as np

# Writing data
with h5py.File('data.h5', 'w') as f:
    dset = f.create_dataset('main_data', data=np.random.rand(100, 100))
    dset.attrs['units'] = 'meters'
    grp = f.create_group('subgroup')
    grp.create_dataset('results', data=[1, 2, 3])

# Reading data
with h5py.File('data.h5', 'r') as f:
    data_slice = f['main_data'][0:10, 0:10] # Only read 100 elements
    units = f['main_data'].attrs['units']
    print(f"Group content: {list(f['subgroup'].keys())}")

关键规则

✅ 应该做
  • 使用上下文管理器 - 始终使用 with h5py.File(...) as f:,确保即使发生错误也会关闭文件。
  • 使用分块 - 对于大型数据集,指定 chunks=True 或手动设置形状,以针对特定切片模式优化访问速度。
  • 启用压缩 - 使用 compression="gzip" 为大型数值数组节省磁盘空间。
  • 使用描述性名称 - 使用组对数据进行逻辑组织(例如,/experiment1/sensorA/raw)。
  • 在属性中存储元数据 - 不要为单位或时间戳创建单独的文本文件;应将它们附加到数据集上。
  • 检查成员是否存在 - 访问前使用 "name" in group,以避免 KeyError。
❌ 不应该做
  • 误用 'w' 模式打开文件 - 'w' 模式会覆盖现有文件。请改用 'a'(追加/读写)或 'r+'(读写)。
  • 将整个数据集加载到 RAM - 除非确定数据集能放入内存,否则避免使用 data = f['large_dataset'][:]。
  • 存储数千个小型数据集 - HDF5 针对大型数组进行了优化。对于数百万个微小标量,请使用单个数组或其他数据库。
  • 忘记关闭文件 - 未关闭的 HDF5 文件可能会损坏或被锁定。

反模式(绝不要这样做)

import h5py
import numpy as np

# ❌ BAD: Manual file closing (unsafe)
f = h5py.File('data.h5', 'w')
f.create_dataset('x', data=np.arange(10))
f.close() # If an error happened above, this never runs!

# ✅ GOOD: Context manager
with h5py.File('data.h5', 'w') as f:
    f.create_dataset('x', data=np.arange(10))

# ❌ BAD: Storing metadata as strings inside a dataset
f.create_dataset('meta', data=np.array(['unit: meter', 'date: 2024']))

# ✅ GOOD: Using Attributes
dset = f.create_dataset('data', data=np.random.rand(10))
dset.attrs['unit'] = 'meter'
dset.attrs['date'] = '2024'

# ❌ BAD: Inefficient chunking (one row at a time when you read columns)
# f.create_dataset('big', shape=(10000, 10000), chunks=(1, 10000))

数据集创建与配置

高级选项
with h5py.File('optimized.h5', 'w') as f:
    # 1. Resizable dataset (maxshape)
    dset = f.create_dataset('growing', 
                            shape=(100,), 
                            maxshape=(None,), # Allow growth in 1st dimension
                            dtype='float32')
    
    # 2. Compression and Chunking
    f.create_dataset('compressed', 
                     data=np.random.randn(1000, 1000),
                     chunks=(100, 100), 
                     compression="gzip", 
                     compression_opts=4) # 4 is a good balance
    
    # 3. Filling with default values
    f.create_dataset('default', shape=(10, 10), fillvalue=-1.0)

使用组

导航和迭代
with h5py.File('nested.h5', 'w') as f:
    f.create_group('raw/2024/january')
    f.create_group('raw/2024/february')

# Recursive iteration
def print_structure(name, obj):
    print(name)

with h5py.File('nested.h5', 'r') as f:
    f.visititems(print_structure) # Visits every dataset and group

# Accessing via path
feb_data = f['/raw/2024/february']

性能优化

1. 分块策略

块是可读取或写入的最小数据单位。

  • 如果通常逐行读取:chunks=(1, n_cols)。
  • 如果读取数据块:chunks=(100, 100)。
  • 如果不确定:chunks=True 可让 h5py 自动推测。
2. SWMR(单写入者多读取者)

允许写入者向文件追加内容,同时其他进程实时读取该文件。

# Writer
f = h5py.File('live.h5', 'w', libver='latest')
f.swmr_mode = True

# Reader
f = h5py.File('live.h5', 'r', libver='latest', swmr=True)
3. Core 驱动程序(内存中的 HDF5)

使用 HDF5 结构,但将其完全保留在 RAM 中以提升速度,并可选择保存到磁盘。

# Create an HDF5 file in memory
f = h5py.File('memfile.h5', 'w', driver='core', backing_store=True)

实用工作流

1. 存储机器学习训练数据
def save_ml_dataset(X, y, filename):
    with h5py.File(filename, 'w') as f:
        # Create datasets for images and labels
        f.create_dataset('images', data=X, compression="lzf") # LZF is fast
        f.create_dataset('labels', data=y)
        
        # Add metadata
        f.attrs['n_samples'] = X.shape[0]
        f.attrs['input_shape'] = X.shape[1:]
        f.attrs['classes'] = np.unique(y)

# Use cases: training on data that exceeds RAM
2. 大型模拟记录器
def log_simulation_step(filename, step_idx, data_array):
    with h5py.File(filename, 'a') as f:
        if 'simulation' not in f:
            # Initialize resizable dataset
            f.create_dataset('simulation', 
                            shape=(0, *data_array.shape),
                            maxshape=(None, *data_array.shape),
                            chunks=(1, *data_array.shape))
            
        dset = f['simulation']
        dset.resize(step_idx + 1, axis=0)
        dset[step_idx] = data_array
3. 批量图像存储
def store_images(image_files, h5_file):
    with h5py.File(h5_file, 'w') as f:
        grp = f.create_group('microscopy_data')
        for i, img_path in enumerate(image_files):
            # Load your image here
            img_data = np.random.rand(512, 512) 
            dset = grp.create_dataset(f'img_{i:04d}', data=img_data)
            dset.attrs['original_path'] = img_path

常见问题与解决方案

“数据集已存在”错误
# ❌ Problem: f.create_dataset('x', ...) fails if 'x' exists
# ✅ Solution: Delete first or use a check
if 'x' in f:
    del f['x']
f.create_dataset('x', data=new_data)
文件锁定问题
# ❌ Problem: "OSError: Unable to open file (file locking disabled on this file system)"
# This often happens on network drives (NFS).

# ✅ Solution: Set environment variable before running script
import os
os.environ['HDF5_USE_FILE_LOCKING'] = 'FALSE'
import h5py
存储 Unicode 字符串

HDF5 对字符串的支持很复杂。

# ❌ Problem: Storing lists of strings can sometimes cause issues in older versions
# ✅ Solution: Use special string types
dt = h5py.string_dtype(encoding='utf-8')
dset = f.create_dataset('strings', (100,), dtype=dt)
dset[0] = "Научные данные"

h5py 是处理大型数值数据的工业级方式。通过结合 NumPy 的灵活性和 HDF5 的强大功能,它能确保您的科学数据井然有序、易于访问且处理迅速。

评论

支持 Markdown