Восстановление координат с помощью Python-Xarray - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть файл 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 работал, но установка переменной обратно на набор данных не работает. После многих попыток я решил напрямую изменить координаты "lon", потому что они связаны с Datavariable "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, если кто-то может указать, почему мой первый подход к обеим проблемам не работает?

Ответы [ 3 ]

0 голосов
/ 03 ноября 2018

Это не решение Python, но если вы используете Linux и у вас есть nco, вы можете набрать

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

согласно этому ответу здесь Как изменить диапазон долготы в NetCDF

0 голосов
/ 03 ноября 2018

Я прошу прощения за однострочник, но именно так я решил эту проблему: d = d.assign_coords(longitude=(((d.longitude + 180) % 360) - 180)).sortby('longitude') Вы должны работать на уровне Dataset, а не на DataArray.

0 голосов
/ 02 ноября 2018

Есть один принцип, который объясняет, почему оба ваших начальных подхода не сработали. В Dataset переменные имеют значения вдоль координат. Координаты в Dataset существуют отдельно от переменных. У вас может быть три переменные U, V и W, которые все изменяются по некоторой координате longitude в наборе данных. Сами по себе, для U и V хорошо иметь значения longitude в разных порядках, но в наборе данных они должны иметь одинаковый порядок.

Когда вы назначаете переменную для набора данных, в котором у набора данных уже есть координата переменной, xarray автоматически переупорядочит эту переменную, чтобы иметь такой же порядок, что и у набора данных. Это также будет делать приятные вещи, такие как добавление nan значений везде, где переменная не имеет значений для данной координаты в наборе данных.

Вот пример, где я сделал Dataset и DataArray, которые оба имеют координаты долготы, но в обратном направлении. Когда я присваиваю 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 ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...