如何使用 h5py 创建可变长度的 ascii 编码字符串

how to create variable length ascii encoded string with h5py

我想使用 python 和 h5py 编写可变长度字符串。如果我使用

dset = grp.create_dataset('data_set_name',{1},dtype=h5py.special_dtype(vlen=str))
dset[0] = 'some_string'

然后h5dump告诉我

   DATASET "data_set_name" {
      DATATYPE  H5T_STRING {
         STRSIZE H5T_VARIABLE;
         STRPAD H5T_STR_NULLTERM;
         CSET H5T_CSET_UTF8;
         CTYPE H5T_C_S1;
      }
      DATASPACE  SIMPLE { ( 1 ) / ( 1 ) }
      DATA {
      (0): "some_string"
      }
   }

已使用 utf-8 字符编码。但是,我想要正常的 ascii 编码,当 h5dump 会声明

   DATASET "data_set_name" {
      DATATYPE  H5T_STRING {
         STRSIZE H5T_VARIABLE;
         STRPAD H5T_STR_NULLTERM;
         CSET H5T_CSET_ASCII;
         CTYPE H5T_C_S1;
      }
      DATASPACE  SIMPLE { ( 1 ) / ( 1 ) }
      DATA {
      (0): "some_string"
      }
   }

如何使用 h5py 实现?或者这是不可能的?

在 unicode 是默认字符串类型的 Py3 会话中,我必须将 ASCII 保存为字节串。从 http://docs.h5py.org/en/latest/strings.html

汲取灵感
In [1]: import h5py
In [2]: f=h5py.File('test.h5','w')
In [3]: grp=f.create_group('test')

In [5]: dset=grp.create_dataset('string',(3,), dtype=h5py.special_dtype(vlen=str))
In [6]: dset
Out[6]: <HDF5 dataset "string": shape (3,), type "|O">
In [7]: dset[0]='astring'
In [8]: dset[1]=b'astring'
In [9]: dset
Out[9]: <HDF5 dataset "string": shape (3,), type "|O">
In [10]: dset[:]
Out[10]: array(['astring', 'astring', ''], dtype=object)

所以 Python 字符串类型都保存为 unicode。

In [11]: dset.attrs['string']='unicode string'
In [12]: dset.attrs['bytes']=b'byte string'
In [13]: dset
Out[13]: <HDF5 dataset "string": shape (3,), type "|O">
In [14]: dset.attrs
Out[14]: <Attributes of HDF5 object at 2880654668>
In [15]: list(dset.attrs.items())
Out[15]: [('string', 'unicode string'), ('bytes', b'byte string')]

对于属性,保留字符串类型。

In [16]: dset2=grp.create_dataset('bstring', (3,), dtype=h5py.special_dtype(vlen=bytes))
In [17]: dset2[0]='astring'
In [19]: dset2[1]=b'astring'
In [22]: dset2[:]
Out[22]: array([b'astring', b'astring', b''], dtype=object)

这两次都写了字节串。

In [25]: f.close()

和转储

In [26]: !h5dump test.h5
HDF5 "test.h5" {
GROUP "/" {
   GROUP "test" {
      DATASET "bstring" {
         DATATYPE  H5T_STRING {
            STRSIZE H5T_VARIABLE;
            STRPAD H5T_STR_NULLTERM;
            CSET H5T_CSET_ASCII;
            CTYPE H5T_C_S1;
         }
         DATASPACE  SIMPLE { ( 3 ) / ( 3 ) }
         DATA {
         (0): "astring", "astring", NULL
         }
      }
      DATASET "string" {
         DATATYPE  H5T_STRING {
            STRSIZE H5T_VARIABLE;
            STRPAD H5T_STR_NULLTERM;
            CSET H5T_CSET_UTF8;
            CTYPE H5T_C_S1;
         }
         DATASPACE  SIMPLE { ( 3 ) / ( 3 ) }
         DATA {
         (0): "astring", "astring", NULL
         }
         ATTRIBUTE "bytes" {
            DATATYPE  H5T_STRING {
               STRSIZE H5T_VARIABLE;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
            DATASPACE  SCALAR
            DATA {
            (0): "byte string"
            }
         }
         ATTRIBUTE "string" {
            DATATYPE  H5T_STRING {
               STRSIZE H5T_VARIABLE;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_UTF8;
               CTYPE H5T_C_S1;
            }
            DATASPACE  SCALAR
            DATA {
            (0): "unicode string"
            }
         }
      }
   }
}
}

所以指定 bytes 而不是 str 可以在 Py3 中实现。