H5PY - 如何存储许多不同尺寸的2D阵列

时间:2017-01-04 13:53:39

标签: python hdf5 h5py

我想使用Python将收集的数据(从计算机模拟)组织到hdf5文件中。 我测量了许多时间步长内某个空间区域内所有原子的位置和速度[x,y,z,vx,vy,vz]。当然,原子数随着时间步长而变化。

最小的例子如下:

[
[ [x1,y1,z1,vx1,vy1,vz1], [x2,y2,z2,vx2,vy2,vz2] ],
[ [x1,y1,z1,vx1,vy1,vz1], [x2,y2,z2,vx2,vy2,vz2], [x3,y3,z3,vx3,vy3,vz3] ] 
]

(2个时间步, 第一次步骤:2个原子, 第二步:3个原子)

我的想法是在Python中创建一个存储所有信息的hdf5数据集。在每个时间步,它应该存储所有原子的所有位置/速度的2d数组,即

dataset[0] = [ [x1,y1,z1,vx1,vy1,vz1], [x2,y2,z2,vx2,vy2,vz2] ]
dataset[1] = [ [x1,y1,z1,vx1,vy1,vz1], [x2,y2,z2,vx2,vy2,vz2], [x3,y3,z3,vx3,vy3,vz3] ].

我认为这个想法很明确。但是,我很难定义具有不同数组长度的数据集的正确数据类型。

我的代码如下所示:

import numpy as np
import h5py

file = h5py.File ('file.h5','w')

columnNo = 6    
rowtype = np.dtype("%sfloat32" % columnNo)
dt = h5py.special_dtype( vlen=np.dtype(rowtype) )

dataset = file.create_dataset("dset", (2,), dtype=dt)

print dataset.value

testarray = np.array([[1.,2.,3.,2.,3.,4.],[1.,2.,3.,2.,3.,4.]])
print testarray

dataset[0] = testarray
print dataset[0]

然而,这不起作用。当我运行脚本时,我收到错误消息“AttributeError:'float'对象没有属性'dtype'。” 似乎我定义的dtype是错误的。

有人看到应该如何正确定义吗?

非常感谢, 斯文

2 个答案:

答案 0 :(得分:0)

您的案例中的错误已被隐藏,但在尝试将testarray分配给dataset时很明显:

Traceback (most recent call last):
  File "stack41465480.py", line 26, in <module>
    dataset[0] = testarray
  File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper (/build/h5py-GhwtGD/h5py-2.6.0/h5py/_objects.c:2577)
 ...
  File "h5py/_conv.pyx", line 712, in h5py._conv.ndarray2vlen (/build/h5py-GhwtGD/h5py-2.6.0/h5py/_conv.c:6171)
AttributeError: 'float' object has no attribute 'dtype'

我不熟悉special_dtypevlen,但我能够将numpy结构化数组写入h5py

import numpy as np
import h5py

file = h5py.File ('file.h5','w')

columnNo = 6    
# rowtype = np.dtype("%sfloat32" % columnNo)
rowtype = np.dtype([('f0', '<f4',(6,))])
dt = h5py.special_dtype( vlen=np.dtype(rowtype) )

print('rowtype',rowtype)
print('dt',dt)
dataset = file.create_dataset("dset", (2,), dtype=rowtype)

print('value')
print(dataset.value[0])

arr = np.ones((2,),dtype=rowtype)
print(repr(arr))
dataset[0] = arr[0]
print(dataset.value)

testarray = np.array([([1.,2.,3.,2.,3.,4.],),([2.,3.,4.,1.,2.,3.],)], dtype=rowtype)
print(repr(testarray))

dataset[1] = testarray[1]
print(dataset.value)
print(dataset.value['f0'])
制造

1316:~/mypy$ python3 stack41465480.py 
rowtype [('f0', '<f4', (6,))]
dt object
value
([0.0, 0.0, 0.0, 0.0, 0.0, 0.0],)
array([([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],), ([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],)], 
      dtype=[('f0', '<f4', (6,))])
[([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],) ([0.0, 0.0, 0.0, 0.0, 0.0, 0.0],)]
array([([1.0, 2.0, 3.0, 2.0, 3.0, 4.0],), ([2.0, 3.0, 4.0, 1.0, 2.0, 3.0],)], 
      dtype=[('f0', '<f4', (6,))])
[([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],) ([2.0, 3.0, 4.0, 1.0, 2.0, 3.0],)]
[[ 1.  1.  1.  1.  1.  1.]
 [ 2.  3.  4.  1.  2.  3.]]

答案 1 :(得分:0)

感谢您的快速回答。它帮助了很多。

如果我现在只是将数据集的数据类型更改为

dtype = dt,

我得到了我想要的东西。

这里,Python代码(为了完整性):

import numpy as np
import h5py

file = h5py.File ('file.h5','w')

columnNo = 6

rowtype = np.dtype([('f0', '<f4',(6,))])
dt = h5py.special_dtype( vlen=np.dtype(rowtype) )

print('rowtype',rowtype)
print('dt',dt)
dataset = file.create_dataset("dset", (2,), dtype=dt)

# print('value')
# print(dataset.value[0])

arr = np.ones((3,),dtype=rowtype)
# print(repr(arr))
dataset[0] = arr
# print(dataset.value)

testarray = np.array([([1.,2.,3.,2.,3.,4.],),([2.,3.,4.,1.,2.,3.],)], dtype=rowtype)
# print(repr(testarray))

dataset[1] = testarray
print(dataset.value)
for i in range(2): print dataset[i]

并输出相应的输出

('rowtype', dtype([('f0', '<f4', (6,))]))
('dt', dtype('O'))
[ array([([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],),
       ([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],), ([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],)], 
      dtype=[('f0', '<f4', (6,))])
 array([([1.0, 2.0, 3.0, 2.0, 3.0, 4.0],), ([2.0, 3.0, 4.0, 1.0, 2.0, 3.0],)], 
      dtype=[('f0', '<f4', (6,))])]
[([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],) ([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],)
 ([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],)]
[([1.0, 2.0, 3.0, 2.0, 3.0, 4.0],) ([2.0, 3.0, 4.0, 1.0, 2.0, 3.0],)]

只是为了正确:我的原始代码中的问题是我的行类型数据结构的错误定义,对吗?

最佳, 斯文