[英]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)>
一種方法可能是循環變量coords標識的變量,如temp.coords
,尋找time
, longitude
和latitude
的standard_name
屬性。 但是許多數據集似乎並不包含所有變量的standard_name
屬性。
我猜測另一種方法是尋找在units
屬性,並試圖找出他們是否有合適的units
屬性(例如degrees_east
或degrees_west
為longitude
,等)。
有沒有更好的辦法?
MetPy包中包含一些用於系統坐標識別的幫助器。 您可以在MetPy教程的xarray中看到它的工作原理。 例如,如果您想要一個名為temp
的DataArray的時間坐標(假設它來自已被MetPy解析的數據集),您只需調用:
temp.metpy.time
這是通過根據CF約定解析坐標元數據在內部完成的。
這是一個簡短的例子:
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 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慣例。 它們正是出於這個原因而存在。 所以我建議將這個問題分成兩部分:
standard_name
屬性的邏輯) standard_name
屬性)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.