【问题标题】:H5PY - How to store many 2D arrays of different dimensionsH5PY - 如何存储许多不同维度的二维数组
【发布时间】:2017-05-18 20:12:36
【问题描述】:

我想使用 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 数据集来存储所有信息。在每个时间步,它应该存储所有原子的所有位置/速度的二维数组,即

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 是错误的。

有人知道它应该如何正确定义吗?

非常感谢, 斯文

【问题讨论】:

    标签: python hdf5 h5py


    【解决方案1】:

    您的情况下的错误已被掩埋,但很明显它发生在尝试将 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.]]
    

    【讨论】:

      【解决方案2】:

      感谢您的快速回答。帮了大忙。

      如果我现在简单地将数据集的数据类型更改为

      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],)]
      

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

      最好, 斯文

      【讨论】:

        猜你喜欢
        • 2017-07-28
        • 1970-01-01
        • 2016-10-14
        • 1970-01-01
        • 1970-01-01
        • 2021-04-24
        • 2015-12-02
        • 1970-01-01
        • 2018-05-20
        相关资源
        最近更新 更多