繁体   English   中英

使用 Python-Xarray 重新网格坐标

[英]Regridding coordinates with Python-Xarray

我有一个 NetCDF 文件,其中的变量存储在 0 到 360 度经度。 我想将其转换为 -180 到 180 度。 这应该是一项相当简单的任务,但出于某种原因,我似乎无法使教程中给出的一些示例得到解决。

ds = xr.open_dataset(file_)   
>ds
<xarray.Dataset>
Dimensions:  (lev: 1, lon: 720, time: 1460)
Coordinates:
* lon      (lon) float64 0.0 0.5 1.0 1.5 2.0 2.5 ... -2.5 -2.0 -1.5 -1.0 -0.5
* lev      (lev) float32 1.0
* time     (time) datetime64[ns] 2001-01-01 ... 2001-12-31T18:00:00
Data variables:
 V        (time, lev, lon) float32 13.281297 11.417505 ... -19.312767

我尝试使用Dataset.assign_coord的帮助

ds.V.assign_coords(lon=((ds.V.lon + 180) % 360 - 180)) 
#gives me a new array with lon -180 to 180
ds['V'] = ds.V.assign_coords(lon=((ds.V.lon + 180) % 360 - 180))
# didn't modify the V for some reason?

因此,assign_coords 起作用,但将变量设置回 Dataset 不起作用。 经过多次尝试,我想直接修改坐标“lon”,因为它们通过字典链接到数据变量“V”。

ds.coords['lon'] = (ds.coords['lon'] + 180) % 360 - 180
#solves the problem!

我遇到的第二个问题是根据上述修改的经度对数据变量进行排序。 我试过

 ds['V'] = ds.V.sortby(ds.lon)
 >ds.V 

 # the array is not sorted according to -180 to 180 values

但是当我对数据集进行排序并分配它时,它就起作用了。

ds = ds.sortby(ds.lon) # now my dataset is sorted to -180 to 180 degrees lon

如果有人能指出为什么我对这两个问题的第一种方法不起作用,这对我理解 xarrays 会非常有帮助?

我为d = d.assign_coords(longitude=(((d.longitude + 180) % 360) - 180)).sortby('longitude')道歉,但这正是我解决这个问题的方法: d = d.assign_coords(longitude=(((d.longitude + 180) % 360) - 180)).sortby('longitude')你应该在Dataset级别工作,而不是在DataArray

有一个原则可以解释为什么您的两种初始方法都不起作用。 Dataset ,变量沿坐标具有值。 坐标在Dataset集中与变量分开存在。 您可能有三个变量UVW ,它们都沿数据集中的某个坐标longitude变化。 就其本身而言, UVlongitude值可以按不同的顺序排列,但在数据集中它们必须具有相同的顺序。

当您将变量分配给数据集已经具有变量坐标的数据集时, xarray将自动重新排序该变量以具有与数据集相同的排序。 它也会做一些不错的事情,比如在变量没有数据集中给定坐标的值的地方添加nan值。

这是一个示例,我创建了一个DatasetDataArray ,它们都具有经度坐标,但方向相反。 当我将DataArray分配给Dataset ,坐标会自动反转。

In[17]: ds
Out[17]: 
<xarray.Dataset>
Dimensions:    (longitude: 10)
Coordinates:
  * longitude  (longitude) float64 360.0 320.0 280.0 240.0 200.0 160.0 120.0 ...
Data variables:
    *empty*

In [18]: da
Out[18]: 
<xarray.DataArray (longitude: 10)>
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
Coordinates:
  * longitude  (longitude) float64 0.0 40.0 80.0 120.0 160.0 200.0 240.0 ...

In [19]: ds['v'] = da

In [20]: ds['v']
Out[20]: 
<xarray.DataArray 'v' (longitude: 10)>
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
Coordinates:
  * longitude  (longitude) float64 360.0 320.0 280.0 240.0 200.0 160.0 120.0 ...

这是一个类似的示例,它会自动添加nan

In [27]: ds
Out[27]: 
<xarray.Dataset>
Dimensions:    (longitude: 10)
Coordinates:
  * longitude  (longitude) float64 360.0 320.0 280.0 240.0 200.0 160.0 120.0 ...
Data variables:
    *empty*

In [28]: da
Out[28]: 
<xarray.DataArray (longitude: 3)>
array([ 0.,  0.,  0.])
Coordinates:
  * longitude  (longitude) float64 0.0 40.0 80.0

In [29]: ds['v'] = da

In [30]: ds['v']
Out[30]: 
<xarray.DataArray 'v' (longitude: 10)>
array([ nan,  nan,  nan,  nan,  nan,  nan,  nan,   0.,   0.,   0.])
Coordinates:
  * longitude  (longitude) float64 360.0 320.0 280.0 240.0 200.0 160.0 120.0 ...

这不是一个 python 解决方案,但如果你在 linux 上并且有 nco 你可以输入

ncap2 -O -s 'where(lon>180) lon=lon-360' ifile ofile

根据这里的答案如何更改 NetCDF 中的经度范围

cdo 可以快速解决这些问题,例如:

cdo sellonlatbox,-180,180,-90,90 a.nc b.nc

a.nc 是你的数据,b.nc 是你想要的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM