Skip to content

Commit be43928

Browse files
committed
Update _hdf5.py
增加了写数组到hdf5的功能,进行了数据的基本测试,是一个二次封装接口,能够更方便的写入数组
1 parent 0a4db94 commit be43928

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

src/mtmhdf/_hdf5.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
from netCDF4 import Dataset, Variable
2+
import numpy as np
3+
24

35
class HDF5(Dataset):
46
@staticmethod
@@ -50,3 +52,59 @@ def _jump(fp: Dataset, path="/"):
5052
else:
5153
return HDF5._jump(subnode_fp, subnode_path)
5254

55+
56+
@staticmethod
57+
def write(fp: Dataset, data:np.ndarray|np.ma.MaskedArray, varname:str, dimensions:tuple[str, ...], datatype:str = None, scale_factor=1.0, add_offset=0.0, **kwargs):
58+
# convert data to numpy.ma.MaskedArray
59+
if isinstance(data, np.ma.MaskedArray):
60+
xm = data
61+
elif isinstance(data, np.ndarray):
62+
xm = np.ma.masked_invalid(data)
63+
else:
64+
raise ValueError("data must be a numpy.ndarray or numpy.ma.MaskedArray")
65+
66+
# check dimensions
67+
shape = xm.shape
68+
if len(dimensions) != len(shape):
69+
raise ValueError("dimensions (tuple) and array shape (tuple) must have the same length")
70+
for i, dimension in enumerate(dimensions):
71+
if dimension not in fp.dimensions:
72+
fp.createDimension(dimension, shape[i])
73+
else:
74+
if (dsize := shape[i]) != (fsize:=fp.dimensions[dimension].size):
75+
raise ValueError(f"dimensions ({dimension}: {dsize}) must have the same size in the file ({dimension}: {fsize})")
76+
77+
# check datatype
78+
if datatype is None:
79+
datatype = xm.dtype
80+
else:
81+
# 将 datatype (如 'i2', 'int16') 转换为 numpy dtype 对象
82+
dt = np.dtype(datatype)
83+
84+
# 只有目标类型是整数时,才需要考虑截断(防止 Overflow)
85+
if np.issubdtype(dt, np.integer):
86+
# 1. 获取目标整数类型的理论最大/最小值
87+
info = np.iinfo(dt)
88+
i_min, i_max = info.min, info.max
89+
print(i_min, i_max)
90+
91+
# 3. 转换为物理值的范围
92+
# 公式: Physical = Integer * scale + offset
93+
lim1 = i_min * scale_factor + add_offset
94+
lim2 = i_max * scale_factor + add_offset
95+
xm = np.ma.masked_outside(xm, lim1, lim2)
96+
97+
# create variable
98+
v = fp.createVariable(varname=varname, datatype=datatype, dimensions=dimensions, **kwargs)
99+
100+
# set scale_factor and add_offset
101+
v.scale_factor = scale_factor
102+
v.add_offset = add_offset
103+
v.set_auto_maskandscale(True)
104+
105+
# write data
106+
xm.data[xm.mask] = 0 # fill invalid values with 0
107+
xm.fill_value = 0
108+
v[:] = xm
109+
110+
return v

0 commit comments

Comments
 (0)