将包含多维 numpy 数组和一维列表的元组存储到 HDF5
Storing tuple containing multidimensional numpy array and 1-D list to HDF5
我正在尝试以下操作:
SPECIAL_TYPE = np.dtype([("arr", h5py.special_dtype(vlen=np.uint8)),
("int1", np.uint8),
("str", h5py.special_dtype(vlen=str)),
("int2", np.uint8),
("int3", np.uint8),
("list", h5py.special_dtype(vlen=np.uint8)),
("int4", np.uint8)])
db = f.create_dataset("db", (1,1), chunks=True, maxshape=(None, 1), dtype=SPECIAL_TYPE)
db.resize((N,1))
for i, idx in enumerate(range(N)):
arr = np.zeros((3,3), dtype=np.uint8)
db[i] = (arr,i, 'a', i, i, [0,1,2,3,4,5,6,7,8,9,10,11], i)
由于多维数组和元组的列表元素,上面的代码对我来说失败了。
充其量,它似乎只将数组的第一行存储在元组中(似乎无法解决此问题),同时在尝试将列表存储在元组中时抛出错误。
我是否遗漏了一些允许以这种方式存储元组列表的方法?
注意:我遇到过这些讨论:
1) https://github.com/h5py/h5py/issues/876
2) Inexplicable behavior when using vlen with h5py
并怀疑不可能像我希望的那样直接存储元组(主要是由于 vlen
可能只适用于一维数组?)。
请原谅我对这个问题的无知...我是 HDF5 的新手。
谢谢!
用你的 dtype 我可以创建一个数组:
In [37]: np.array([_],dtype=SPECIAL_TYPE)
Out[37]:
array([ (array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]], dtype=uint8), 1, 'a', 1, 1, list([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]), 1)],
dtype=[('arr', 'O'), ('int1', 'u1'), ('str', 'O'), ('int2', 'u1'), ('int3', 'u1'), ('list', 'O'), ('int4', 'u1')])
但是尝试用它创建 dataset
,即使是 1d,也会让我脱离解释器:
In [38]: f=h5py.File('vlentest.h5','w')
In [39]: db = f.create_dataset('db',(10,), dtype=SPECIAL_TYPE)
In [40]: db[:]
Segmentation fault (core dumped)
有两个问题 - vlen
是否适用于二维数组,是否适用于复合 dtype?您正在用二维数组中的 dtype 中的多个 vlen 推动边界。
您是否看过在复合数据类型中使用 vlen
的文档或示例?
注意 h5py
如何在 numpy 中实现 vlen
- 它将那些字段定义为 'O' 对象数据类型。它在数组中存储一个指针,而不是可变长度对象本身。通常对象 dtype 数组不能用 h5py
保存。但是这些字段必须有一些附加注释,h5py
用来将指针转换为 HDF5
接受的那种结构。
探索 vlen str 的存储方式。
实验,用一些小的东西陈述
In [14]: f = h5py.File('temp.h5')
In [15]: db1 = f.create_dataset('db1',(5,), dtype=dt1)
In [16]: db2 = f.create_dataset('db2',(5,), dtype=dt2)
In [17]: db1[:]
Out[17]:
array([('',), ('',), ('',), ('',), ('',)],
dtype=[('str', 'O')])
In [18]: db2[:]
Out[18]:
array([('', 0), ('', 0), ('', 0), ('', 0), ('', 0)],
dtype=[('str', 'O'), ('int4', '<i4')])
设置一些 db1
值:
In [24]: db1[0]=('a',)
In [25]: db1[1]=('ab',)
In [26]: db1[:]
Out[26]:
array([('a',), ('ab',), ('',), ('',), ('',)],
dtype=[('str', 'O')])
db2
的工作原理相同:
In [30]: db2[0]=('abc',10)
In [31]: db2[1]=('abcde',6)
In [32]: db2[:]
Out[32]:
array([('abc', 10), ('abcde', 6), ('', 0), ('', 0), ('', 0)],
dtype=[('str', 'O'), ('int4', '<i4')])
2 个 vlen 字符串也有效:
In [34]: dt3 = np.dtype([("str1", h5py.special_dtype(vlen=str)),("str2", h5py.special_dtype(vlen=str))])
In [35]: db3 = f.create_dataset('db3',(3,), dtype=dt3)
In [36]: db3[:]
Out[36]:
array([('', ''), ('', ''), ('', '')],
dtype=[('str1', 'O'), ('str2', 'O')])
In [37]: db3[0] = ('abc','defg')
In [38]: db3[1] = ('abcd','de')
In [39]: db3[:]
Out[39]:
array([('abc', 'defg'), ('abcd', 'de'), ('', '')],
dtype=[('str1', 'O'), ('str2', 'O')])
和数组 vlen
In [41]: dt4 = np.dtype([("str1", h5py.special_dtype(vlen=str)),("list", h5py.special_dtype(vlen=np.int))])
In [42]: dt4
Out[42]: dtype([('str1', 'O'), ('list', 'O')])
In [43]: db4 = f.create_dataset('db4',(3,), dtype=dt4)
In [47]: db4[0]=('abcdef',np.arange(5))
In [48]: db4[1]=('abc',np.arange(3))
In [49]: db4[:]
Out[49]:
array([('abcdef', array([0, 1, 2, 3, 4])), ('abc', array([0, 1, 2])),
('', array([], dtype=int32))],
dtype=[('str1', 'O'), ('list', 'O')])
但我不能使用 list
In [50]: db4[2]=('abc',[1,2,3,4])
--------------------------------------------------------------------------
AttributeError: 'list' object has no attribute 'dtype'
h5py
保存数组,而不是列表。显然,这也适用于这些嵌套值。 http://docs.h5py.org/en/latest/special.html 有用列表设置 vlen
的例子,但它首先转换为数组。
如果我尝试保存二维数组,它只会写入一维
In [59]: db4[2]=('abc',np.ones((2,2),int))
In [60]: db4[:]
Out[60]:
array([('abcdef', array([0, 1, 2, 3, 4])), ('abc', array([0, 1, 2])),
('abc', array([1, 1]))],
dtype=[('str1', 'O'), ('list', 'O')])
这个 dtype 有效:
In [21]: dt1 = np.dtype([("str1", h5py.special_dtype(vlen=str)),('f1',int),("list", h5py.special_dtype(vlen=np.int))])
这会执行核心转储
In [30]: dt1 = np.dtype([("f0", h5py.special_dtype(vlen=np.uint8)),('f1',int),("f2", h5py.special_dtype(vlen=np.int))])
这是 vlen uint8
的问题,还是首先是 vlen 的问题?
我正在尝试以下操作:
SPECIAL_TYPE = np.dtype([("arr", h5py.special_dtype(vlen=np.uint8)),
("int1", np.uint8),
("str", h5py.special_dtype(vlen=str)),
("int2", np.uint8),
("int3", np.uint8),
("list", h5py.special_dtype(vlen=np.uint8)),
("int4", np.uint8)])
db = f.create_dataset("db", (1,1), chunks=True, maxshape=(None, 1), dtype=SPECIAL_TYPE)
db.resize((N,1))
for i, idx in enumerate(range(N)):
arr = np.zeros((3,3), dtype=np.uint8)
db[i] = (arr,i, 'a', i, i, [0,1,2,3,4,5,6,7,8,9,10,11], i)
由于多维数组和元组的列表元素,上面的代码对我来说失败了。
充其量,它似乎只将数组的第一行存储在元组中(似乎无法解决此问题),同时在尝试将列表存储在元组中时抛出错误。
我是否遗漏了一些允许以这种方式存储元组列表的方法?
注意:我遇到过这些讨论:
1) https://github.com/h5py/h5py/issues/876
2) Inexplicable behavior when using vlen with h5py
并怀疑不可能像我希望的那样直接存储元组(主要是由于 vlen
可能只适用于一维数组?)。
请原谅我对这个问题的无知...我是 HDF5 的新手。
谢谢!
用你的 dtype 我可以创建一个数组:
In [37]: np.array([_],dtype=SPECIAL_TYPE)
Out[37]:
array([ (array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]], dtype=uint8), 1, 'a', 1, 1, list([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]), 1)],
dtype=[('arr', 'O'), ('int1', 'u1'), ('str', 'O'), ('int2', 'u1'), ('int3', 'u1'), ('list', 'O'), ('int4', 'u1')])
但是尝试用它创建 dataset
,即使是 1d,也会让我脱离解释器:
In [38]: f=h5py.File('vlentest.h5','w')
In [39]: db = f.create_dataset('db',(10,), dtype=SPECIAL_TYPE)
In [40]: db[:]
Segmentation fault (core dumped)
有两个问题 - vlen
是否适用于二维数组,是否适用于复合 dtype?您正在用二维数组中的 dtype 中的多个 vlen 推动边界。
您是否看过在复合数据类型中使用 vlen
的文档或示例?
注意 h5py
如何在 numpy 中实现 vlen
- 它将那些字段定义为 'O' 对象数据类型。它在数组中存储一个指针,而不是可变长度对象本身。通常对象 dtype 数组不能用 h5py
保存。但是这些字段必须有一些附加注释,h5py
用来将指针转换为 HDF5
接受的那种结构。
实验,用一些小的东西陈述
In [14]: f = h5py.File('temp.h5')
In [15]: db1 = f.create_dataset('db1',(5,), dtype=dt1)
In [16]: db2 = f.create_dataset('db2',(5,), dtype=dt2)
In [17]: db1[:]
Out[17]:
array([('',), ('',), ('',), ('',), ('',)],
dtype=[('str', 'O')])
In [18]: db2[:]
Out[18]:
array([('', 0), ('', 0), ('', 0), ('', 0), ('', 0)],
dtype=[('str', 'O'), ('int4', '<i4')])
设置一些 db1
值:
In [24]: db1[0]=('a',)
In [25]: db1[1]=('ab',)
In [26]: db1[:]
Out[26]:
array([('a',), ('ab',), ('',), ('',), ('',)],
dtype=[('str', 'O')])
db2
的工作原理相同:
In [30]: db2[0]=('abc',10)
In [31]: db2[1]=('abcde',6)
In [32]: db2[:]
Out[32]:
array([('abc', 10), ('abcde', 6), ('', 0), ('', 0), ('', 0)],
dtype=[('str', 'O'), ('int4', '<i4')])
2 个 vlen 字符串也有效:
In [34]: dt3 = np.dtype([("str1", h5py.special_dtype(vlen=str)),("str2", h5py.special_dtype(vlen=str))])
In [35]: db3 = f.create_dataset('db3',(3,), dtype=dt3)
In [36]: db3[:]
Out[36]:
array([('', ''), ('', ''), ('', '')],
dtype=[('str1', 'O'), ('str2', 'O')])
In [37]: db3[0] = ('abc','defg')
In [38]: db3[1] = ('abcd','de')
In [39]: db3[:]
Out[39]:
array([('abc', 'defg'), ('abcd', 'de'), ('', '')],
dtype=[('str1', 'O'), ('str2', 'O')])
和数组 vlen
In [41]: dt4 = np.dtype([("str1", h5py.special_dtype(vlen=str)),("list", h5py.special_dtype(vlen=np.int))])
In [42]: dt4
Out[42]: dtype([('str1', 'O'), ('list', 'O')])
In [43]: db4 = f.create_dataset('db4',(3,), dtype=dt4)
In [47]: db4[0]=('abcdef',np.arange(5))
In [48]: db4[1]=('abc',np.arange(3))
In [49]: db4[:]
Out[49]:
array([('abcdef', array([0, 1, 2, 3, 4])), ('abc', array([0, 1, 2])),
('', array([], dtype=int32))],
dtype=[('str1', 'O'), ('list', 'O')])
但我不能使用 list
In [50]: db4[2]=('abc',[1,2,3,4])
--------------------------------------------------------------------------
AttributeError: 'list' object has no attribute 'dtype'
h5py
保存数组,而不是列表。显然,这也适用于这些嵌套值。 http://docs.h5py.org/en/latest/special.html 有用列表设置 vlen
的例子,但它首先转换为数组。
如果我尝试保存二维数组,它只会写入一维
In [59]: db4[2]=('abc',np.ones((2,2),int))
In [60]: db4[:]
Out[60]:
array([('abcdef', array([0, 1, 2, 3, 4])), ('abc', array([0, 1, 2])),
('abc', array([1, 1]))],
dtype=[('str1', 'O'), ('list', 'O')])
这个 dtype 有效:
In [21]: dt1 = np.dtype([("str1", h5py.special_dtype(vlen=str)),('f1',int),("list", h5py.special_dtype(vlen=np.int))])
这会执行核心转储
In [30]: dt1 = np.dtype([("f0", h5py.special_dtype(vlen=np.uint8)),('f1',int),("f2", h5py.special_dtype(vlen=np.int))])
这是 vlen uint8
的问题,还是首先是 vlen 的问题?