python-xarray: open_mfdataset concat по двум измерениям

У меня есть файлы, которые состоят из 10 ансамблей и 35 файлов времени. Один из этих файлов выглядит так:

>>> xr.open_dataset('ens1/CCSM4_ens1_07ic_19820701-19820731_NPac_Jul.nc')
<xarray.Dataset>
Dimensions:    (ensemble: 1, latitude: 66, longitude: 191, time: 31)
Coordinates:
  * ensemble   (ensemble) int32 1
  * latitude   (latitude) float32 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 ...
  * longitude  (longitude) float32 100.0 101.0 102.0 103.0 104.0 105.0 106.0 ...
  * time       (time) datetime64[ns] 1982-07-01 1982-07-02 1982-07-03 ...
Data variables:
    u10m       (time, latitude, longitude) float64 -1.471 -0.05933 -1.923 ...
Attributes:
    CDI:                       Climate Data Interface version 1.6.5 (http://c...
    history:                   Wed Nov 22 21:54:08 2017: ncks -O -d longitude...
    Conventions:               CF-1.4
    CDO:                       Climate Data Operators version 1.6.5 (http://c...
    nco_openmp_thread_number:  1
    NCO:                       4.3.7

Когда я использую open_mfdataset, файлы объединяются вместе измерение времени и измерение ансамбля отбрасываются (возможно, потому что оно имеет размер 1)?

>>> xr.open_mfdataset('ens*/*NPac*.nc')
<xarray.Dataset>
Dimensions:    (latitude: 66, longitude: 191, time: 10850)
Coordinates:
  * latitude   (latitude) float32 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 ...
  * longitude  (longitude) float32 100.0 101.0 102.0 103.0 104.0 105.0 106.0 ...
  * time       (time) datetime64[ns] 1982-07-01 1982-07-02 1982-07-03 ...
Data variables:
    u10m       (time, latitude, longitude) float64 -1.471 -0.05933 -1.923 ...

Я не уверен, можно ли конкатенировать и по измерению ансамбля?

Я провел простой тест, используя merge, как указано здесь Ошибка при использовании функции xarray open_mfdataset, но это не удается:

>>> ds = xr.open_mfdataset('ens1/*NPac*')
<xarray.Dataset>
Dimensions:    (ensemble: 1, latitude: 66, longitude: 191, time: 1085)
Coordinates:
  * ensemble   (ensemble) int32 1
  * latitude   (latitude) float32 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 ...
  * longitude  (longitude) float32 100.0 101.0 102.0 103.0 104.0 105.0 106.0 ...
  * time       (time) datetime64[ns] 1982-07-01 1982-07-02 1982-07-03 ...
Data variables:
    u10m       (time, latitude, longitude) float64 -1.471 -0.05933 -1.923 ...
>>> ds2 = xr.open_mfdataset('ens2/*NPac*')
<xarray.Dataset>
Dimensions:    (ensemble: 1, latitude: 66, longitude: 191, time: 1085)
Coordinates:
  * ensemble   (ensemble) int32 2
  * latitude   (latitude) float32 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 ...
  * longitude  (longitude) float32 100.0 101.0 102.0 103.0 104.0 105.0 106.0 ...
  * time       (time) datetime64[ns] 1982-07-01 1982-07-02 1982-07-03 ...
Data variables:
    u10m       (time, latitude, longitude) float64 3.992 2.099 -0.3162 ...
>>> ds3 = xr.merge([ds, ds2])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/nethome/rxb826/local/bin/miniconda3/lib/python3.6/site-packages/xarray/core/merge.py", line 513, in merge
    variables, coord_names, dims = merge_core(dict_like_objects, compat, join)
  File "/nethome/rxb826/local/bin/miniconda3/lib/python3.6/site-packages/xarray/core/merge.py", line 432, in merge_core
    variables = merge_variables(expanded, priority_vars, compat=compat)
  File "/nethome/rxb826/local/bin/miniconda3/lib/python3.6/site-packages/xarray/core/merge.py", line 166, in merge_variables
    merged[name] = unique_variable(name, variables, compat)
  File "/nethome/rxb826/local/bin/miniconda3/lib/python3.6/site-packages/xarray/core/merge.py", line 85, in unique_variable
    % (name, out, var))
xarray.core.merge.MergeError: conflicting values for variable 'u10m' on objects to be combined:
first value: <xarray.Variable (time: 1085, latitude: 66, longitude: 191)>
dask.array<shape=(1085, 66, 191), dtype=float64, chunksize=(31, 66, 191)>
Attributes:
    long_name:  10m U component of wind
    units:      m s**-1
second value: <xarray.Variable (time: 1085, latitude: 66, longitude: 191)>
dask.array<shape=(1085, 66, 191), dtype=float64, chunksize=(31, 66, 191)>
Attributes:
    long_name:  10m U component of wind
    units:      m s**-1

Я использую v0.10.0 (спасибо за недавнее обновление!)


person Ray Bell    schedule 29.11.2017    source источник


Ответы (3)


xarray.open_mfdataset не поддерживает 2-мерные слияния. Что вам нужно сделать, так это использовать concat по второму измерению:

import os
import xarray as xr

ens_list = []
for num in range(1, 11):
     ens = 'ens%d' % num
     ens_list.append(xr.open_mfdataset(os.path.join(ens, '*NPac*')))
ds = xr.concat(ens_list, dim='ensemble')

Это распространенная проблема, с которой сталкиваются пользователи xarray. Однако написать обобщенную подпрограмму ND concat довольно сложно.

person jhamman    schedule 29.11.2017
comment
спасибо за soln @jhamman, как изменится ваш soln, если netCDF не имеют измерения ensemble, а имеют только lat, lon и time. - person user308827; 03.08.2018

Я написал следующую функцию в качестве обходного пути для моего собственного варианта использования: https://gist.github.com/jnhansen/fa474a536201561653f60ea33045f4e2

Он работает с произвольными размерами, но в настоящее время требует, чтобы одни и те же переменные существовали в каждом файле / наборе данных.

В моем случае у меня есть несколько плиток (разделенных, например, lat, lon и time):

ds = auto_merge('data/part*.nc')

Это будет выполнено немедленно, поскольку оно возвращает только представление данных (как и xarray.open_mfdataset).

person jhansen    schedule 03.08.2018
comment
спасибо @jhansen, значит, в примере в этом посте u10m должен существовать в каждом файле netCDF? Это кажется разумным предположением - person user308827; 03.08.2018
comment
можешь привести небольшой пример, как вызвать свой код? Я также протестирую свои собственные наборы данных и приму. Благодарность! - person user308827; 03.08.2018
comment
Конечно, я добавил в свой ответ однострочный пример. Должно быть так просто! И да, именно переменная u10m (или что-то еще) должна существовать в каждом файле. Я на самом деле не проверял, что произойдет, если этого не произойдет ... - person jhansen; 04.08.2018

xarray теперь поддерживает N-D конкатенацию. Поскольку ваши данные имеют одномерные координаты, вы можете просто сделать

ds = xr.open_mfdataset('ens*/*NPac*.nc', combine='by_coords')

и он должен автоматически комбинировать их по порядку! Это должно работать даже для измерения ensemble, так как вы также дали ему координату.

Также см. этот ответ на очень похожий вопрос.

person ThomasNicholas    schedule 17.12.2019