带单位的复合类型

Compound types with units

我想知道在 HDF5 中是否可以将物理单元与复合数据类型的组件一起存储?

举个例子,考虑地理坐标。可以用不同的方式指示位置。纬度、经度和半径可以以度和公里为单位给出,但以弧度和米为单位指定也一样好。如何使用 h5py 存储此信息?

HDF5 不知道单位。因此,您必须创建一个适当的模式来记录坐标数据的单位。你如何做到这一点完全取决于你。我至少可以想到 3 种方法:

  1. 方法一为每个坐标创建1个数据集
    -- 单位是用数据集级别的属性定义的
  2. 方法 2 使用所有 3 个坐标创建 1 个复合数据集。
    -- 单位由 3 个组级属性定义,并且作为 字段(列)名称
  3. 方法 3 使用所有 3 个坐标创建 1 个复合数据集。
    -- 单位定义有 3 个附加字段(列)(字符串数据类型)
    -- 属性不用于保存单位。

这是一个代码示例,它使用一小组数据(每个坐标 10 个值)演示了所有 3 种方法。希望这能给你一些想法。

import h5py
import numpy as np

long_arr = np.random.uniform(-180.,180., 10)
lat_arr  = np.random.uniform(-90.,90., 10)
rad_arr  = np.random.uniform(6357.,6378., 10)

with h5py.File('SO_65977032.h5', mode='w') as h5f:

# Method 1 creates 1 dataset for each coordinate
# Units are defined with a dataset level attribute  
    h5f.create_group('Method_1')
    
    h5f['Method_1'].create_dataset('Long', data=long_arr)
    h5f['Method_1']['Long'].attrs['Units']='Degrees'

    h5f['Method_1'].create_dataset('Lat', data=lat_arr)
    h5f['Method_1']['Lat'].attrs['Units']='Degrees'

    h5f['Method_1'].create_dataset('Radius', data=rad_arr)
    h5f['Method_1']['Radius'].attrs['Units']='km'

# Method 2 creates 1 compound dataset with all 3 coordinates.
# Units are defined with 3 group level attributes AND as part of the field (column) names    
    h5f.create_group('Method_2')

    llr_dt = [ ('Long(Deg)', float), ('Lat(Deg)', float), ('Radius(km)', float)  ]

    h5f['Method_2'].create_dataset('Coords', dtype=llr_dt, shape=(10,))
    h5f['Method_2']['Coords']['Long(Deg)'] = long_arr
    h5f['Method_2']['Coords'].attrs['Long Units']='Degrees'

    h5f['Method_2']['Coords']['Lat(Deg)'] = lat_arr
    h5f['Method_2']['Coords'].attrs['Lat Units']='Degrees'

    h5f['Method_2']['Coords']['Radius(km)'] = rad_arr   
    h5f['Method_2']['Coords'].attrs['Radius Units']='km'
    
# Method 3 creates 1 compound dataset with all 3 coordinates.
# Units are defined with 3 additional fields (columns) (datatype of strings)
# Attributes are NOT used to save Units.
    h5f.create_group('Method_3')

    llru_dt = [ ('Long', float),  ('Long_units', 'S8'), 
                ('Lat', float),   ('Lat_units', 'S8'),
                ('Radius', float), ('Rad_units', 'S8')  ]

    h5f['Method_3'].create_dataset('Coords', dtype=llru_dt, shape=(10,))
    h5f['Method_3']['Coords']['Long'] = long_arr
    h5f['Method_3']['Coords']['Long_units'] = [ 'Degree' for _ in range(10) ]

    h5f['Method_3']['Coords']['Lat'] = lat_arr
    h5f['Method_3']['Coords']['Lat_units'] = [ 'Degree' for _ in range(10) ]

    h5f['Method_3']['Coords']['Radius'] = rad_arr
    h5f['Method_3']['Coords']['Rad_units'] = [ 'km' for _ in range(10) ]