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

使用h5py从生成器向H5文件追加结构化数组失败求助

使用h5py追加结构化数组数据失败排查

我尝试用h5py向数据集追加数据,但一直没成功,想找出问题所在。numpy_arr是一个生成器,用来产出结构化numpy数组,相关代码如下:

import h5py
import numpy as np

dt_vlstr = h5py.string_dtype(encoding='utf-8')
dt_vlstr_arr = h5py.vlen_dtype(dt_vlstr) 
dt_int = np.dtype('i4')

constructor = {
    'names':['ark','dates','events','iso639','views','dublincore','catch_word','colors', 'bw'],
    'formats': [
        dt_vlstr, #ark
        dt_vlstr_arr, #dates
        dt_vlstr_arr, #events
        dt_vlstr_arr, #iso639
        dt_int, #lecture
        dt_vlstr, #dublincore
        dt_vlstr_arr, #catch_word
        dt_int, #colors
        dt_int, #bw
    ]}

compound = np.dtype(constructor)

def mapping2numpy(generators):
    for i in (generators):
        numpy_arr = np.array([(
                            i['ark'],
                            i['dates'].astype(dt_vlstr), 
                            i['events'].astype(dt_vlstr), 
                            i['iso639'].astype(dt_vlstr), 
                            i['views'], 
                            i['dublincore'], 
                            i['catch_word'].astype(dt_vlstr),
                            i['colors'],
                            i["bw"])],dtype=compound)

        yield numpy_arr

numpy_arr = mapping2numpy(data)

with h5py.File('file.h5', 'w') as h5f:
    group = h5f.create_group('metadata')
    dataset = group.create_dataset('records', (1,1), maxshape=(None,1), 
                                                                    compression="lzf", 
                                                                    dtype=compound, 
                                                                    fletcher32=True,
                                                                    chunks=(1,1))

with h5py.File('file.h5', 'a') as h5f: 
    dset = h5f['metadata/records']
    for data in numpy_arr:
        dset.resize( (dset.shape[0]+1, 1) )
        dset[-1,:] = data

问题排查与修正

核心问题点

  • 维度不匹配:创建数据集时用了二维形状(1,1),但生成器产出的是(1,)的一维数组,赋值dset[-1,:] = data时形状不兼容。
  • 冗余数组嵌套:生成器每次产出(1,)的数组,没必要多套一层,直接产出单个结构化元素更合理。
  • 初始数据占位冗余:初始创建的(1,1)数据集会留下一行空数据,后续追加会导致数据错位。

修正后的代码

import h5py
import numpy as np

dt_vlstr = h5py.string_dtype(encoding='utf-8')
dt_vlstr_arr = h5py.vlen_dtype(dt_vlstr) 
dt_int = np.dtype('i4')

constructor = {
    'names':['ark','dates','events','iso639','views','dublincore','catch_word','colors', 'bw'],
    'formats': [
        dt_vlstr,      # ark
        dt_vlstr_arr,  # dates
        dt_vlstr_arr,  # events
        dt_vlstr_arr,  # iso639
        dt_int,        # views(原注释写错为lecture)
        dt_vlstr,      # dublincore
        dt_vlstr_arr,  # catch_word
        dt_int,        # colors
        dt_int         # bw
    ]}

compound = np.dtype(constructor)

def mapping2numpy(generators):
    for i in generators:
        # 直接产出单个结构化元素,避免冗余数组嵌套
        yield (
            i['ark'],
            i['dates'].astype(dt_vlstr), 
            i['events'].astype(dt_vlstr), 
            i['iso639'].astype(dt_vlstr), 
            i['views'], 
            i['dublincore'], 
            i['catch_word'].astype(dt_vlstr),
            i['colors'],
            i["bw"]
        )

numpy_arr = mapping2numpy(data)

# 创建空的一维可扩展数据集
with h5py.File('file.h5', 'w') as h5f:
    group = h5f.create_group('metadata')
    dataset = group.create_dataset('records', shape=(0,), maxshape=(None,), 
                                   compression="lzf", dtype=compound, 
                                   fletcher32=True, chunks=(1,))

# 追加数据
with h5py.File('file.h5', 'a') as h5f: 
    dset = h5f['metadata/records']
    for data in numpy_arr:
        dset.resize(dset.shape[0] + 1, axis=0)
        dset[-1] = data  # 直接赋值最后一行,形状完全匹配

修正说明

  1. 调整数据集为一维:结构化数组用一维存储更符合逻辑,避免二维维度带来的形状匹配问题。
  2. 简化生成器输出:去掉不必要的数组嵌套,直接生成单个结构化元素,赋值更直观。
  3. 初始创建空数据集:从0行开始追加,避免初始空数据占位导致的冗余。
  4. 修正注释错误:将原代码中views的错误注释lecture修正。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:42:07