使用 python xarray 创建一个空的 netCDF4 char 变量

问题描述 投票:0回答:2

我想创建一个 netCDF 文件,它存储多个变量及其关联的坐标,以及一个可用于存储各种投影元数据的空 char 变量。

我试过这个:

import xarray as xr
import numpy as np

#example variable
A=np.array([[1,2],[3,4]])

#example coords
x=np.array([10,20])
y=np.array([30,40])

#example netcdf creation with xarray
data_vars={'A':(['y','x'],A),
           'projection':np.str()}
coords={'x':x,
        'y':y}
dataset = xr.Dataset(data_vars=data_vars, coords=coords)
dataset['projection'].attrs['EPSG']='3413'

dataset.to_netcdf('path/to/file.nc')

此方法将“projection”变量保存为 char 类型,但也为其分配了一个空字符串:

<xarray.Dataset>
Dimensions:     (x: 2, y: 2)
Coordinates:
  * y           (y) int64 30 40
  * x           (x) int64 10 20
Data variables:
    A           (y, x) int64 1 2 3 4
    projection  |S1 ''

使用 xarray,如何创建“投影”变量,使其只是一个 char 类型(此处表示为 |S1)且没有维度的空存储变量?

如有任何帮助,我们将不胜感激。

python char netcdf python-xarray
2个回答
0
投票

TL;DR:我还没有评论的声誉,只能部分解决问题,因为

to_netcdf
强制为变量分配维度。

我对这个问题有了进一步的了解(同样的问题,为 CRS 设置变量):

data_vars = {
    'A':(['y','x'],A),
    'crs': np.array(b'', dtype='|S1')
}

其中

|S1
是单字节字符串的 numpy 数据类型。在 Python 3 中,它的使用是不鼓励的,但似乎使用 GDAL 设置了 CRS 的 netCDF 是由
xarray.open_dataset
以完全相同的方式读取的,所以我尝试复制它。当使用
to_netcdf
写回时,一切看起来都很好 - 但是
ncdump -h
告诉我,我的 crs 变量被分配了一个以前不存在的维度
string1
:

$ ncdump -h impact.nc                                                                                                             
[truncated]
    char crs(string1) ;
        crs:inverse_flattening = 298.257223563 ;
        crs:spatial_ref = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS…"
[truncated]

我想我可以通过简单地从Python调用gdal_translate来添加CRS来解决

解决这个问题。


0
投票
我也遇到了 xarray 强制不必要的 string1 维度的问题。我通过使用 xarray 完成除 crs 定义之外的所有操作,然后使用 netCDF4 API 在文件中附加一个空的 char crs 变量及其所需的属性,从而解决了这个问题,如下所示:

from netCDF4 import Dataset import xarray as xr import numpy as np #example variable A=np.array([[1,2],[3,4]]) #example coords x=np.array([10,20]) y=np.array([30,40]) #example netcdf creation with xarray data_vars={'A':(['y','x'],A)} coords={'x':x, 'y':y} dataset = xr.Dataset(data_vars=data_vars, coords=coords) dataset.to_netcdf('corrected.nc') fid = Dataset('corrected.nc', 'a', format='NETCDF4') crs = fid.createVariable('crs', 'S1', ()) crs.EPSG = "3413" fid.close()
这产生了我对 ncdump 的期望:

ncdump -h corrected.nc netcdf corrected { dimensions: y = 2 ; x = 2 ; variables: int64 A(y, x) ; int64 x(x) ; int64 y(y) ; char crs ; crs:EPSG = "3413" ; }
    
© www.soinside.com 2019 - 2024. All rights reserved.