如何在XArray中识别时间,经度和纬度坐标?

时间:2018-11-25 16:27:07

标签: python python-xarray

确定xarray dataArray对象的哪个坐标包含longitudelatitudetime的最佳方法是什么?

典型的dataArray可能看起来像这样:

<xarray.Dataset>
Dimensions:    (ensemble: 9, lat: 224, lon: 464, time: 12054)
Coordinates:
  * lat        (lat) float64 25.06 25.19 25.31 25.44 ... 52.56 52.69 52.81 52.94
  * lon        (lon) float64 -124.9 -124.8 -124.7 ... -67.31 -67.19 -67.06
  * time       (time) datetime64[ns] 1980-01-01 1980-01-02 ... 2012-12-31
Dimensions without coordinates: ensemble
Data variables:
    elevation  (lat, lon) float64 dask.array<shape=(224, 464), chunksize=(224, 464)>
    temp       (ensemble, time, lat, lon) float64 dask.array<shape=(9, 12054, 224, 464), chunksize=(1, 287, 224, 464)>

一种方法可能是遍历变量坐标所标识的变量,例如temp.coords,寻找standard_nametime和{{ 1}}。但是许多数据集似乎并未为所有变量都包含longitude属性。

我想另一种方法是搜索latitude属性,并尝试识别它们是否具有适当的standard_name属性(例如{{1}的unitsunits }等)。

有更好的方法吗?

4 个答案:

答案 0 :(得分:2)

MetPy package包括一些用于像这样的系统坐标识别的助手。您可以在xarray with MetPy tutorial中了解其工作原理。例如,如果您想要一个名为temp的DataArray的时间坐标(假设它来自MetPy解析的数据集),则只需调用:

temp.metpy.time

这是通过根据CF conventions解析坐标元数据在内部完成的。

这是一个简短的例子:

import xarray as xr
import metpy.calc as mpcalc

ds = xr.tutorial.load_dataset('air_temperature')
ds = ds.metpy.parse_cf()

x,y,t = ds['air'].metpy.coordinates('x','y','time')

print([coord.name for coord in (x, y, t)])

产生:

['lon', 'lat', 'time']

答案 1 :(得分:0)

您可能可以使用xarray filter_by执行与以下代码类似的操作:

def x_axis(nc):
    xnames = ['longitude', 'grid_longitude', 'projection_x_coordinate']
    xunits = [
        'degrees_east',
        'degree_east',
        'degree_E',
        'degrees_E',
        'degreeE',
        'degreesE',
    ]
    xvars = list(set(
        nc.get_variables_by_attributes(
            axis=lambda x: x and str(x).lower() == 'x'
        ) +
        nc.get_variables_by_attributes(
            standard_name=lambda x: x and str(x).lower() in xnames
        ) +
        nc.get_variables_by_attributes(
            units=lambda x: x and str(x).lower() in xunits
        )
    ))
    return xvars

答案 2 :(得分:0)

如果仅寻找充当索引的特殊坐标,则可以遍历ds.indexes并对其名称进行一些字符串解析。像这样:

ds = xr.tutorial.load_dataset('air_temperature')
ds.lat.attrs.pop('standard_name')

for k in ds.indexes.keys():
    v = ds[k]
    sn = v.attrs.get('standard_name')
    if not sn:
        if 'lon' in k:
            v.attrs.update(standard_name='longitude')
            continue
        if 'lat' in k:
            v.attrs.update(standard_name='latitude')
            continue
        if 'time' in k or k in ['day', 't', 'month', 'year']:
            v.attrs.update(standard_name='time')

答案 3 :(得分:0)

我认为我们应该严重依赖CF公约。正是由于这个原因,它们才存在。因此,我建议将这个问题分为两个部分:

  • 修复非CF投诉数据集(为此目的可能是一个小的库,它可能包含将通用变量名转换为适当的standard_name属性的逻辑)
  • 解析CF投诉数据集(可以利用standard_name属性)