我使用 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")
我正在寻找一种可靠、简洁的方法来获取该变量坐标的值,特别是时间和垂直水平。一种有效但不切实际的方法是请求和使用整个数据集。
功能性但不切实际的方法
获取数据
import xarray as xr
query.all_times()
data = ncss.get_data(query)
datastore = xr.backends.NetCDF4DataStore(data)
使用 MetPy 的 xarray 访问器xarray.Dataset
获取数据
ds = xr.open_dataset(datastore).metpy.parse_cf()
从构成xarray.DataArray
获取坐标轴
对于数据集的每个变量作为xarray.DataArray
,调用ds.VARIABLE.metpy.DIMENSION
都会让 MetPy 自动返回适当的坐标变量(无论它叫什么名字,例如lat
、lon
、time
、time1
、altitude_above_msl
、isobaric3
、height_above_ground1
(,其中DIMENSION
是time
、vertical
、x
和y
之一。
获取值
在这种情况下,ds.Absolute_vorticity_isobaric.metpy.time
返回ds.time
,ds.Absolute_vorticity_isobaric.metpy.vertical
返回ds.isobaric2
。将.values
添加到调用中仅返回具有我一直尝试获取的值的numpy.ndarray
。因此,调用ds.Absolute_vorticity_isobaric.metpy.time.values
会产生以下内容(下面截断(:
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.values
和ds.Absolute_vorticity_isobaric.metpy.vertical.values
将只返回 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()