Python-xarray:open_mfdataset沿两个维度合并拼接。

8
我有一些文件,由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(感谢最近的更新!)

3个回答

12

xarray.open_mfdataset不支持2D合并。你需要做的是沿着第二个维度使用concat

xarray.open_mfdataset不支持二维合并。您需要在第二个维度上使用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连接例程相当困难。


2
感谢@jhamman提供的解决方案,如果netCDF文件没有“ensemble”维度,只有“lat”,“lon”和“time”,那么您的解决方案会如何改变呢? - user308827

3
我编写了下面的函数作为我的特定用例的解决方法:https://gist.github.com/jnhansen/fa474a536201561653f60ea33045f4e2 它可以处理任意维度,但目前需要每个文件/数据集中存在相同的变量。
在我的情况下,我有很多块瓦片(沿着例如latlontime进行分割): ds = auto_merge('data/part*.nc') 这将立即执行,因为它只返回数据的视图(就像xarray.open_mfdataset一样)。

谢谢@jhansen,所以在这篇文章中的例子中,这是否意味着每个netCDF文件中都应该存在u10m?这似乎是一个合理的假设。 - user308827
1
你能提供一个如何调用你的代码的小例子吗?我也会使用自己的数据集进行测试并接受。谢谢! - user308827
当然,我在回复中添加了一行示例。应该很简单!是的,确切地说,变量u10m(或其他名称)应该存在于每个文件中。事实上,如果没有这个变量,我还没有测试会发生什么... - jhansen

2

xarray现在支持N-D连接。由于您的数据具有1-D维度坐标,因此您可以简单地执行以下操作:

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

它应该自动按顺序组合它们!如果您还给出一个坐标,则它甚至可以适用于ensemble维度。

另请参见此答案,它回答了一个非常类似的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接