如何保存xarray.DataArray将128个复杂的数据传输到netcd

2024-07-03 07:42:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个xarray数据集中有一些复杂的数据(numpy dtype complex128),我想用它保存到\u netcdf。我得到以下错误:

TypeError: illegal primitive data type, must be one of dict_keys(['S1', 'i1', 'u1', 'i2', 'u2', 'i4', 'u4', 'i8', 'u8', 'f4', 'f8']), got complex128

我知道我正在向底层netCDF4传递不支持的数据类型。我还在netcdf4的复合数据类型上找到了https://unidata.github.io/netcdf4-python/。但不幸的是,我不知道如何将其应用于我的问题,因为我没有直接使用netcdf4库。在

我可以在保留数据类型(使用xarray.DataArray.to_netcdf)的同时将数据类型complex128保存到netcdf吗?在

MWE:

^{pr2}$

Tags: 数据numpydatatype错误netcdfnetcdf4数据类型
2条回答

NetCDF作为文件格式不支持复杂数据。显然,地球科学的用户并不强烈需要保存复杂的值。在

也就是说,您确实可以使用某种特殊约定将complex128数据写入netCDF文件,例如使用自定义复合数据类型。这与h5py使用的方法类似。这确实需要在xarray中实现:pull请求是受欢迎的。在

在当前版本的xarray中,序列化复杂值有两个选项:

  1. 使用engine='h5netcdf'。这使用h5py的约定来编写复杂的数据。不幸的是,这会导致一个无效的netCDF文件unreadable by netCDF-C。 如果您尝试此操作,应该会看到一条警告消息。在xarray的未来版本中,我们可能需要使用诸如to_hdf5()而不是to_netcdf()这样的专用方法来创建这样的无效文件。

  2. 将数据转换为实部和虚部,并将它们保存为单独的变量。从磁盘读回数据时,将它们组合成复杂的值。选择你认为最合适的临时会议。

例如

def save_complex(data_array, *args, **kwargs):
    ds = xarray.Dataset({'real': data_array.real, 'imag': data_array.imag})
    return ds.to_netcdf(*args, **kwargs)

def read_complex(*args, **kwargs):
    ds = xarray.open_dataset(*args, **kwargs)
    return ds['real'] + ds['imag'] * 1j

除了shoyer提供的两个非常好的选择之外,我发现还有另一个解决方案在实践中很有用:

向数据集中添加另一个长度为2的维度,它表示数据的实部和虚部。这类似于将实部和虚部分别存储在不同的变量中,但根据我的经验,在某些情况下可以更好地使用。在

例如,存储维度^ ^ {CD1>}变量,{{< CD2>},其中{{CD3>}是实假想的,^ {CD4}}是任意维,给出了一个与C中的{{a1}的维度^ {< CD4>}相当的一维内存布局,或者C++中的等价{^ < CD7>}。在

阅读和写作是这样的:

def save_complex(dataset, *args, **kwargs):
    ds = dataset.expand_dims('ReIm', axis=-1) # Add ReIm axis at the end
    ds = xarray.concat([ds.real, ds.imag], dim='ReIm')
    return ds.to_netcdf(*args, **kwargs)

def read_complex(*args, **kwargs):
    ds = xarray.open_dataset(*args, **kwargs)
    return ds.isel(ReIm=0) + 1j * ds.isel(ReIm=1)

正如示例所示,这种方法对于数据集(不仅仅是数据数组)很容易实现。在

相关问题 更多 >