如何使用 Siphon 和 MetPy 从 netCDF 网格数据集中获取变量的坐标值数组?

How do I get arrays of coordinate values for a variable from a netCDF gridded dataset using Siphon and MetPy?

我已经使用 Siphon 请求了一个 netCDF 子集,并形成了一个查询来检索边界框内的变量:

from siphon.catalog import TDSCatalog
cat = TDSCatalog("https://thredds.ucar.edu/thredds/catalog/grib/NCEP/GFS/Global_onedeg/catalog.xml?dataset=grib/NCEP/GFS/Global_onedeg/Best")
ncss = cat.datasets[0].subset()
query = ncss.query()
query.variables("Absolute_vorticity_isobaric")
query.lonlat_box(north=34., south=33., west=-102., east=-101.)
query.accept("netcdf4")

我正在寻找一种可靠、简洁的方法来获取该变量坐标的值,特别是时间和垂直水平。一种可行但不切实际的方法是请求并使用 whole 数据集。

实用但不实用的方法

获取数据

import xarray as xr
query.all_times()
data = ncss.get_data(query)
datastore = xr.backends.NetCDF4DataStore(data)

使用MetPy's xarray accessor

获取数据为xarray.Dataset
ds = xr.open_dataset(datastore).metpy.parse_cf()

从成分中获取坐标轴xarray.DataArray

对于作为 xarray.DataArray 的数据集的每个变量,调用 ds.VARIABLE.metpy.DIMENSION 让 MetPy 自动 return 适当的坐标变量(无论它被命名为什么,例如 lat, lon, time, time1, altitude_above_msl, isobaric3, height_above_ground1), 其中 DIMENSIONtimeverticalxy

获取值

在这种情况下,ds.Absolute_vorticity_isobaric.metpy.time returns ds.timeds.Absolute_vorticity_isobaric.metpy.vertical returns ds.isobaric2。将 .values 添加到调用 return 中只是 numpy.ndarray 具有我一直试图获得的值。因此,调用 ds.Absolute_vorticity_isobaric.metpy.time.values 会产生以下结果(下面列出了 t运行):

array(['2019-11-17T00:00:00.000000000', '2019-11-17T03:00:00.000000000',
       '2019-11-17T06:00:00.000000000', ..., '2020-01-02T06:00:00.000000000',
       '2020-01-02T09:00:00.000000000', '2020-01-02T12:00:00.000000000'],
      dtype='datetime64[ns]')

调用 ds.Absolute_vorticity_isobaric.metpy.time.valuesds.Absolute_vorticity_isobaric.metpy.vertical.values 将 return 只是 NumPy 数组,这正是我想要的。

问题

虽然上面确实做了我想要的,但 只花了将近一分半钟 运行 一个变量 ,并且它(我假设) 不必要地对 UCAR 服务器征税。有没有什么方法可以在没有加载所有数据本身的大量开销的情况下获得上面的输出?

如果您关心原始方法的性能,并且只想提取时间和垂直坐标,我建议您使用 OPENDAP 而不是 NCSS 来访问您的数据。这将首先简单地获取元数据,然后将延迟加载您请求的数据(时间和垂直坐标,在您的情况下)。使用 MetPy v0.11 或更新版本,使用您感兴趣的 TDS 目录的示例脚本如下所示:

import metpy
import xarray as xr

from siphon.catalog import TDSCatalog

cat = TDSCatalog("https://thredds.ucar.edu/thredds/catalog/grib/NCEP/GFS/Global_onedeg/catalog.xml?dataset=grib/NCEP/GFS/Global_onedeg/Best")
opendap_url = cat.datasets[0].access_urls['OPENDAP']
ds = xr.open_dataset(opendap_url)

time = ds['Absolute_vorticity_isobaric'].metpy.time.values
vertical = ds['Absolute_vorticity_isobaric'].metpy.vertical.values

print(time)
print(vertical)

在我的系统上 运行 大约需要半秒。

如果您的 MetPy 早于 v0.11,则打开数据集时需要使用 .metpy.parse_cf(),如下所示:

ds = xr.open_dataset(opendap_url).metpy.parse_cf()