You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

批量读取HDF5文件直接切片数据集无需转存的实现方法

多HDF5文件无落地合并切片实现方案

核心逻辑不需要生成持久化的合并文件,两种实现路径可按需选择,都能兼容原有切片、可视化代码逻辑。


方案1:内存直接拼接(推荐,数据量可放进内存时用)

逻辑最简单,和原有单文件读取的代码兼容性最高,全程只在内存中操作,不会生成任何中间文件:

  • 用标准库glob解析入参里的通配符,拿到所有匹配的HDF5文件路径
  • 遍历所有文件,逐个读取jets/truth_hadrons/hits三个数据集存入临时列表
  • 用numpy沿第0维(样本维度)拼接所有数组,得到的合并对象和单文件读取得到的数组结构完全一致,原有切片逻辑不需要做任何修改

可直接复用的代码如下:

import glob
import h5py
import numpy as np

# 解析通配符匹配所有目标文件
file_list = sorted(glob.glob(args.H5file))
if not file_list:
    raise RuntimeError(f"输入路径{args.H5file}未匹配到任何HDF5文件")

jet_cache, had_cache, hit_cache = [], [], []
for file_path in file_list:
    with h5py.File(file_path, 'r') as df:
        print(f"读取文件:{file_path}\n文件包含键:{list(df.keys())}")
        # 和原有单文件读取逻辑完全一致
        jet_cache.append(df['jets'][:])
        had_cache.append(df['truth_hadrons'][:])
        hit_cache.append(df['hits'][:])

# 拼接得到最终合并数据集
jetdset = np.concatenate(jet_cache, axis=0)
haddset = np.concatenate(had_cache, axis=0)
hitdset = np.concatenate(hit_cache, axis=0)

# 后续直接复用原有切片、可视化代码即可

注意事项

  • 所有匹配到的HDF5文件中,三个目标数据集除第一维(样本维)长度可不同外,其余维度尺寸、数据类型必须完全一致,否则拼接会报错,和提到的「所有文件数据格式一致」的前提匹配
  • 脚本运行结束后内存中的数组会自动释放,不会残留任何持久化文件

方案2:虚拟数据集映射(大文件场景用)

如果总数据量太大无法全部加载进内存,可以用h5py原生的虚拟数据集功能,不需要把数据读入内存,也不需要生成合并文件,直接把多个文件的数据集映射为一个逻辑上的完整数据集,切片时才会按需读取对应位置的数据:

import glob
import h5py
import numpy as np

file_list = sorted(glob.glob(args.H5file))
if not file_list:
    raise RuntimeError(f"输入路径{args.H5file}未匹配到任何HDF5文件")

# 读取第一个文件获取数据集基础结构
with h5py.File(file_list[0], 'r') as f:
    jet_base_shape = f['jets'].shape[1:]
    had_base_shape = f['truth_hadrons'].shape[1:]
    hit_base_shape = f['hits'].shape[1:]
    jet_dtype = f['jets'].dtype
    had_dtype = f['truth_hadrons'].dtype
    hit_dtype = f['hits'].dtype

# 遍历所有文件生成虚拟源
jet_sources, had_sources, hit_sources = [], [], []
total_jet_num = total_had_num = total_hit_num = 0
for fp in file_list:
    with h5py.File(fp, 'r') as f:
        jet_n = f['jets'].shape[0]
        had_n = f['truth_hadrons'].shape[0]
        hit_n = f['hits'].shape[0]

        jet_sources.append(h5py.VirtualSource(fp, 'jets', shape=(jet_n, *jet_base_shape), dtype=jet_dtype))
        had_sources.append(h5py.VirtualSource(fp, 'truth_hadrons', shape=(had_n, *had_base_shape), dtype=had_dtype))
        hit_sources.append(h5py.VirtualSource(fp, 'hits', shape=(hit_n, *hit_base_shape), dtype=hit_dtype))

        total_jet_num += jet_n
        total_had_num += had_n
        total_hit_num += hit_n

# 组装虚拟布局
jet_layout = h5py.VirtualLayout(shape=(total_jet_num, *jet_base_shape), dtype=jet_dtype)
had_layout = h5py.VirtualLayout(shape=(total_had_num, *had_base_shape), dtype=had_dtype)
hit_layout = h5py.VirtualLayout(shape=(total_hit_num, *hit_base_shape), dtype=hit_dtype)

jet_offset = had_offset = hit_offset = 0
for src in jet_sources:
    n = src.shape[0]
    jet_layout[jet_offset:jet_offset+n] = src
    jet_offset += n
for src in had_sources:
    n = src.shape[0]
    had_layout[had_offset:had_offset+n] = src
    had_offset += n
for src in hit_sources:
    n = src.shape[0]
    hit_layout[hit_offset:hit_offset+n] = src
    hit_offset += n

# 虚拟数据集支持和普通numpy数组几乎一致的切片语法,按需切片即可,不要直接用[:]拉取全量数据
# 示例:取前100个jet样本:jet_sample = jet_layout[:100]

内容的提问来源于stack exchange,提问作者physicscitizen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:40:36