【问题标题】:How do I get arrays of coordinate values for a variable from a netCDF gridded dataset using Siphon and MetPy?如何使用 Siphon 和 MetPy 从 netCDF 网格数据集中获取变量的坐标值数组?
【发布时间】:2019-12-18 06:21:31
【问题描述】:

我已经使用 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's xarray accessor获取xarray.Dataset的数据

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

从组成xarray.DataArray 获取坐标轴

对于作为xarray.DataArray 的数据集的每个变量,调用ds.VARIABLE.metpy.DIMENSION 会使MetPy 自动返回适当的坐标变量(无论它被命名为什么,例如latlontime、@987654332 @、altitude_above_mslisobaric3height_above_ground1),其中DIMENSIONtimeverticalxy 之一。

获取值

在这种情况下,ds.Absolute_vorticity_isobaric.metpy.time 返回ds.timeds.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.valuesds.Absolute_vorticity_isobaric.metpy.vertical.values 将只返回 NumPy 数组,这正是我所寻求的。

问题

虽然上面的内容确实符合我的要求,但只运行一个变量就花了将近一分半钟的时间,而且它(我认为)不必要地对 UCAR 服务器征税。有没有什么方法可以在没有加载所有数据本身的巨大开销的情况下获得上面的输出?

【问题讨论】:

    标签: python metpy python-siphon


    【解决方案1】:

    如果您担心原始方法的性能,并且只想提取时间和垂直坐标,我建议您使用 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)
    

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

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

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

    【讨论】:

    • 解决了!我建议进行编辑以将.metpy.parse_cf() 附加到语句ds = xr.open_dataset(opendap_url) 以避免出现AttributeError: time attribute is not available. 之类的错误,谢谢您的帮助!
    • 另外,有什么理由必须使用list(cat.datasets.values())[0],而不是cat.datasets[0]?我运行它们时似乎没有任何区别。
    • @SouthlandSooner 你用.metpy.parse_cf() 提出了一个很好的观点,但这仅适用于旧版本的 MetPy(v0.11.0 之前)。我拒绝了编辑,但添加了一条评论来解决它。此外,没有理由不使用较短的 cat.datasets 行(我只是根据在线示例进行修改),因此我还将其合并到编辑后的答案中。感谢您的反馈!
    猜你喜欢
    • 2019-06-23
    • 2021-07-08
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 2016-05-19
    • 2015-10-20
    • 2013-11-15
    • 2019-03-11
    相关资源
    最近更新 更多