如何识别 xarray 中的时间、lon 和 lat 坐标?
How to identify time, lon, and lat coordinates in xarray?
确定 xarray
dataArray
对象的哪些坐标包含 longitude
、latitude
和 time
的最佳方法是什么?
典型的 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
,寻找 time
、longitude
的 standard_name
属性,以及latitude
。但是许多数据集似乎并不包含所有变量的 standard_name
属性。
我想另一种方法是搜索 units
属性并尝试确定它们是否具有适当的 units
属性(例如 degrees_east
或 degrees_west
longitude
,等等)。
有没有更好的方法?
您可能可以使用 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
如果您只是寻找充当索引的特殊坐标,那么您可以遍历 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')
我认为我们应该大量依赖 CF 约定。它们的存在正是出于这个原因。所以我建议把这个问题分成两部分:
- 修复非 CF 投诉数据集(也许用于此目的的小型库是有意义的——它可以包含将常见变量名称转换为适当的
standard_name
属性的逻辑)
- 解析 CF 投诉数据集(可以利用
standard_name
属性)
MetPy package includes some helpers for systematic coordinate identification like this. You can see the basics of how this works in the 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']
确定 xarray
dataArray
对象的哪些坐标包含 longitude
、latitude
和 time
的最佳方法是什么?
典型的 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
,寻找 time
、longitude
的 standard_name
属性,以及latitude
。但是许多数据集似乎并不包含所有变量的 standard_name
属性。
我想另一种方法是搜索 units
属性并尝试确定它们是否具有适当的 units
属性(例如 degrees_east
或 degrees_west
longitude
,等等)。
有没有更好的方法?
您可能可以使用 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
如果您只是寻找充当索引的特殊坐标,那么您可以遍历 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')
我认为我们应该大量依赖 CF 约定。它们的存在正是出于这个原因。所以我建议把这个问题分成两部分:
- 修复非 CF 投诉数据集(也许用于此目的的小型库是有意义的——它可以包含将常见变量名称转换为适当的
standard_name
属性的逻辑) - 解析 CF 投诉数据集(可以利用
standard_name
属性)
MetPy package includes some helpers for systematic coordinate identification like this. You can see the basics of how this works in the 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']