【问题标题】:Writing to compound dataset with variable length string via h5py (HDF5)通过 h5py (HDF5) 写入具有可变长度字符串的复合数据集
【发布时间】:2016-01-19 17:58:31
【问题描述】:

我已经能够使用 h5py 在我的 HDF5 文件中创建一个由无符号整数和可变长度字符串组成的复合数据集,但我无法对其进行写入。

dt = h5py.special_dtype(vlen=str)
dset = fout.create_dataset(ver, (1,), dtype=np.dtype([("time", np.uint64),("value", dt)]))

通过将复合数据集的特定列设置为等于现有的 numpy 数组,我已经相当容易地写入其他复合数据集。

现在我遇到麻烦的是使用可变长度字符串写入复合数据集。 Numpy 不支持可变长度字符串,因此我无法事先创建包含该值的 numpy 数组。

我的下一个想法是将单个值写入相关列,这适用于 unsigned int。但是,当我尝试将字符串写入复合数据集中的可变长度字符串字段时,我得到:

    dset["value"] = str("blah")
  File "D:\Anaconda3\lib\site-packages\h5py\_hl\dataset.py", line 508, in __setitem__
    val = val.astype(numpy.dtype([(names[0], dtype)]))
ValueError: Setting void-array with object members using buffer.

任何指导将不胜感激。

【问题讨论】:

    标签: python numpy hdf5 h5py


    【解决方案1】:

    按照我之前对Inexplicable behavior when using vlen with h5py的回答

    我运行了这个测试(h5py version '2.2.1'):

    In [4]: import h5py
    In [5]: dt = h5py.special_dtype(vlen=str)
    In [6]: f=h5py.File('foo.hdf5')
    In [8]: ds1 = f.create_dataset('JustStrings',(10,), dtype=dt)
    In [10]: ds1[0]='string'
    In [11]: ds1[1]='a longer string'
    In [13]: ds1[2:5]='one_string two_strings three'.split()
    
    In [14]: ds1
    Out[14]: <HDF5 dataset "JustStrings": shape (10,), type "|O4">
    
    In [15]: ds1.value
    Out[15]: 
    array(['string', 'a longer string', 'one_string', 'two_strings', 'three',
           '', '', '', '', ''], dtype=object)
    

    对于像你这样的混合数据类型:

    In [16]: ds2 = f.create_dataset('IntandStrings',(10,),
       dtype=np.dtype([("number",int),('astring',dt)]))
    In [17]: ds2[0]=(1,'astring')
    In [18]: ds2[1]=(10,'a longer string')
    In [19]: ds2[2:4]=[(10,'a longer much string'),(0,'')]
    In [20]: ds2.value
    Out[20]: 
    array([(1, 'astring'), (10, 'a longer string'),
           (10, 'a longer much string'), (0, ''), (0, ''), (0, ''), (0, ''),
           (0, ''), (0, ''), (0, '')], 
          dtype=[('number', '<i4'), ('astring', 'O')])
    

    尝试自行设置字段似乎不起作用

    ds2['astring'][4]='one two three four'
    

    相反,我必须设置整个记录:

    ds2[4]=(123,'one two three four')
    

    尝试设置整个字段会产生相同的错误:

    ds2['astring']='astring'
    

    我将此数据集初始化为(10,),而您的初始化为(1,)。但我认为这是同样的问题。

    不过,我可以设置整个数字字段:

    In [48]: ds2['number']=np.arange(10)
    In [50]: ds2['number']
    Out[50]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    In [51]: ds2.value
    Out[51]: 
    array([(0, 'astring'), (1, 'a longer string'), 
           (2, 'a longer much string'),
           (3, ''), (4, 'one two three four'), (5, ''), 
           (6, ''), (7, ''),
           (8, ''), (9, '')], 
          dtype=[('number', '<i4'), ('astring', 'O')])
    

    【讨论】:

    • 感谢 jpaulj!我是如此接近,但我在兜圈子。感谢您非常彻底的回答。
    猜你喜欢
    • 2021-05-03
    • 2017-06-02
    • 2020-11-18
    • 2018-09-20
    • 1970-01-01
    • 2016-06-05
    • 2016-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多