xarray自动将_FillValue应用于netCDF输出的坐标

9

我正在尝试创建一个符合CF标准的NetCDF文件。使用xarray,我可以使它达到98%的CF标准,但是我遇到了一个问题。当我在创建的文件上执行ncdump时,我看到以下内容:

float lon(lon) ;
    lon:_FillValue = NaNf ;
    lon:long_name = "Longitude" ;
    lon:standard_name = "longitude" ;
    lon:short_name = "lon" ;
    lon:units = "degrees_east" ;
    lon:axis = "X" ;
    lon:valid_min = -180.f ;
    lon:valid_max = 180.f ;
float lat(lat) ;
    lat:_FillValue = NaNf ;
    lat:long_name = "Latitude" ;
    lat:standard_name = "latitude" ;
    lat:short_name = "lat" ;
    lat:units = "degrees_north" ;
    lat:axis = "Y" ;
    lat:valid_min = -90.f ;
    lat:valid_max = 90.f ;
double time(time) ;
    time:_FillValue = NaN ;
    time:standard_name = "time" ;
    time:units = "days since 2006-01-01" ;
    time:calendar = "gregorian" ;

我的数据集坐标是纬度(lat)、经度(lon)和时间(time)。当我使用ds.to_netcdf()将其转换为netcdf格式时,所有的坐标变量都会自动应用填充值,因为它们是浮点数。然而,对于应用了填充值的坐标变量,这违反了CF标准(http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#attribute-appendix)。
我尝试修改编码方式,以使这些特定的变量不被压缩:
import numpy as np
import xarray as xr
import pandas as pd
import datetime as dt

lons = np.arange(-75, -70, .5).astype(np.float32)
lats = np.arange(40,42, .25).astype(np.float32)
[x, y] = np.meshgrid(lons, lats)
u = np.random.randn(1, 8, 10).astype(np.float32)
v = np.random.randn(1, 8, 10).astype(np.float32)
time_index = pd.date_range(dt.datetime.now(), periods=1)

ds = xr.Dataset()
coords = ('time', 'lat', 'lon')
ds['u'] = (coords, np.float32(u))
ds['v'] = (coords, np.float32(v))
ds.coords['lon'] = lons
ds.coords['lat'] = lats
ds.coords['time'] = time_index

encoding = {'lat': {'zlib': False},
            'lon': {'zlib': False},
            'u': {'_FillValue': -999.0,
                  'chunksizes': (1, 8, 10),
                  'complevel': 1,
                  'zlib': True}
            }
ds.to_netcdf('test.nc', encoding=encoding)

我尝试通过更改数据类型来解决,但是没有成功。我不希望使用netCDF4重新加载文件以删除_FillValues。在xarray中是否有内置的方法可以解决这个问题?


有趣的问题,但是像往常一样,提供一个最小工作示例会让其他人更容易地研究这个问题。 - Bart
抱歉,我已经添加了一个测试示例。 - naja
1个回答

16

2022年更新:在较新版本的xarray中,'_FillValue': False 应该替换为 '_FillValue': None。感谢 @Biggsy 在下面的评论中指出。


_FillValue: False 添加到纬度/经度编码似乎可以解决问题:

encoding = {'lat': {'zlib': False, '_FillValue': False},
            'lon': {'zlib': False, '_FillValue': False},
            'u': {'_FillValue': -999.0,
                  'chunksizes': (1, 8, 10),
                  'complevel': 1,
                  'zlib': True}
            }

生成文件的ncdump -h

netcdf test {
dimensions:
    time = 1 ;
    lat = 8 ;
    lon = 10 ;
variables:
    float u(time, lat, lon) ;
        u:_FillValue = -999.f ;
    float v(time, lat, lon) ;
        v:_FillValue = NaNf ;
    float lon(lon) ;
    float lat(lat) ;
    int64 time(time) ;
        string time:units = "days since 2017-08-15 17:41:19.460662" ;
        string time:calendar = "proleptic_gregorian" ;
}

哎呀!经常是一些非常简单的问题。这个方法可行。我之前尝试过_FillValue=None,但由于某种原因,我没有想到使用False! 非常感谢您! - naja
我找不到这方面的文档,所以对我来说只是猜测。False 是在 None 之后的第二次尝试... 如果这个解决方案有效,你可以接受答案以将其从未解决问题列表中移除。 - Bart
2
看起来现在已经改变了(2022),从False变成了None。 - Biggsy
1
谢谢@Biggsy,我已经将更新添加到答案中。 - Bart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接