【问题标题】:How to write data to a compound data using h5py?如何使用 h5py 将数据写入复合数据?
【发布时间】:2020-09-28 17:37:16
【问题描述】:

我知道在c 中,我们可以使用struct 类型轻松构建复合数据集,并逐块分配数据。我目前正在Pythonh5py 中实现类似的结构。

import h5py
import numpy as np 

# we create a h5 file 
f = h5py.File("test.h5") # default is mode "a"


# We define a compound datatype using np.dtype
dt_type = np.dtype({"names":["image","feature"],
                   "formats":[('<f4',(4,4)),('<f4',(10,))]})

# we define our dataset with 5 instances
a = f.create_dataset("test", shape=(5,), dtype=dt_type)

要写入数据,我们可以这样做...

# "feature" array is 1D
a['feature']

输出是

array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)

# Write 1s to data field "feature"
a["feature"] = np.ones((5,10))

array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]], dtype=float32)

问题是当我将二维数组“图像”写入文件时。

a["image"] = np.ones((5,4,4))

ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.

我阅读了文档并进行了研究。不幸的是,我没有找到好的解决方案。我知道我们使用group/dataset 来模拟这种复合数据,但我真的想保留这种结构。有什么好办法吗?

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 当我创建一个具有该形状和 dtype 的数组时,您的 ones 分配有效。 a['image'] = np.ones((5,4,4), 'f4') 有效吗? np.ones 可能默认为float64,而h5py 无法将其转换为float32。也许以后我会用h5py试试。
  • @hpaulj 感谢您的回复。这没用。 dtype 遵循我们在开头定义的内容。在我们的例子中,它是float32,分配的值的类型将被强制为 float32。
  • 我可以用那个 dtype 和 shape 创建一个 numpy 数组,用 np.ones 设置它的“image”字段。 a[:] = arr 有效。 a['image'][:] = np.ones((5,4,4)) 也有效。
  • 我的理解是h5py使用cython代码与HDF5C++ API接口。由于 numpy 数组可以设置字段值,我怀疑我们在这里看到的限制来自 HDF5 本身,而不是来自 h5py 开发人员的一些懒惰。
  • 看一些其他的例子,我们可能需要多注意错误信息和位置。 __setitem__ 代码是 Python。问题可能仅限于二维字段。此外,numpy 在处理多字段索引的方式上做了一些更改。

标签: python numpy h5py


【解决方案1】:

您可以使用 PyTables(又名表)使用所需的数组填充您的 HDF5 文件。您应该将每一行视为一个独立的条目(由 dtype 定义)。因此,“图像”数组存储为 5 个 (4x4) ndarray,而不是单个 (5x4x4) ndarray。 'feature' 数组也是如此。

此示例一次将每个“特征”和“图像”数组添加一行。或者,您可以创建一个 numpy 记录数组,其中两个数组都包含多行数据,然后使用 Table.append() 函数添加。

查看下面的代码来创建文件,然后打开只读来检查数据。

import tables as tb
import numpy as np 

# open h5 file for writing
with tb.File('test1_tb.h5','w') as h5f:

# define a compound datatype using np.dtype
    dt_type = np.dtype({"names":["feature","image"],
                        "formats":[('<f4',(10,)) , ('<f4',(4,4)) ] })

# create empty table (dataset)
    a = h5f.create_table('/', "test1", description=dt_type)

# create dataset row interator
    a_row = a.row
# create array data and append to dataset
    for i in range(5):
        a_row['feature'] = i*np.ones(10)
        a_row['image'] = np.random.random(4*4).reshape(4,4)
        a_row.append()

    a.flush()

# open h5 file read only and print contents
with tb.File('test1_tb.h5','r') as h5fr:
    a = h5fr.get_node('/','test1')
    print (a.coldtypes)
    print ('# of rows:',a.nrows)

    for row in a:
        print (row['feature'])
        print (row['image'])

【讨论】:

    【解决方案2】:

    这篇博文帮助我解决了这个问题: https://www.christopherlovell.co.uk/blog/2016/04/27/h5py-intro.html

    编写复合数据集的关键代码:

    import numpy as np
    import h5py
    
    # Load your dataset into numpy
    audio = np.load(path.join(root_dir, 'X_dev.npy')).astype(np.float32)
    text = np.load(path.join(root_dir, 'T_dev.npy')).astype(np.float32)
    gesture = np.load(path.join(root_dir, 'Y_dev.npy')).astype(np.float32)
    
    # open a hdf5 file
    hf = h5py.File(root_dir+"/dev.hdf5", 'a') 
    
    # create group
    g1 = hf.create_group('dev') 
    
    # put dataset in subgroups
    g1.create_dataset('audio', data=audio)
    g1.create_dataset('text', data=text)
    g1.create_dataset('gesture', data=gesture)
    
    # close the hdf5 file
    hf.close()  
    

    【讨论】:

      猜你喜欢
      • 2016-01-10
      • 2015-09-27
      • 2022-01-23
      • 2021-08-05
      • 2016-04-04
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      • 2017-12-25
      相关资源
      最近更新 更多