如何在Python中使用xarray联接来自多个netCDF文件的数据?

时间:2019-04-01 14:47:04

标签: python concatenation netcdf python-xarray multiple-files

我正在尝试使用Python中的xarray打开多个netCDF文件。这些文件具有相同形状的数据,我想将它们合并,创建一个新的维度。

我试图对xarray.open_mfdataset()使用concat_dim参数,但是它没有按预期工作。下面给出了一个示例,该示例打开了两个文件,它们的温度数据分别为124次,241个纬度和480个经度:

DS = xr.open_mfdataset( 'eraINTERIM_t2m_*.nc', concat_dim='cases' )
da_t2m = DS.t2m

print( da_t2m )

使用此代码,我希望结果数据数组的形状像(例:2,时间:124,纬度:241,经度:480)。但是,其形状为(案例:2,时间:248,纬度:241,经度:480)。 它创建了一个新维度,但也将最左边的维度相加:两个数据集的“时间”维度。 我想知道这是来自“ xarray.open_mfdateset”的错误还是预期的行为,因为两个数据集的“时间”维度都是无限的。

是否有一种方法可以直接使用xarray联接这些文件中的数据并获得上述预期收益?

谢谢。

伴侣

3 个答案:

答案 0 :(得分:2)

在我的评论中,我会尝试以下方法:

def preproc(ds):
    ds = ds.assign({'stime': (['time'], ds.time)}).drop('time').rename({'time': 'ntime'})
    # we might need to tweak this a bit further, depending on the actual data layout
    return ds

DS = xr.open_mfdataset( 'eraINTERIM_t2m_*.nc', concat_dim='cases', preprocess=preproc)

这里的好处是,您可以在重命名原始维度(stime-> time)的同时将原始时间坐标保留在ntime中。

如果一切正常,您应该得到的尺寸为(casesntimelatitudelongitude)。

免责声明:我在最后一个concat循环中执行了类似的操作(效果很好),但是没有测试preprocess方法。

答案 1 :(得分:1)

如果时间不同,则结果有意义。

为简化起见,请暂时忽略一下lat维度,并想象您有两个文件,它们只是两个时间片上的数据。第一个文件的时间步长为1,2,第二个文件的时间步长为3和4。您无法创建一个时间维度仅跨越2个时间片的组合数据集。时间维变量必须具有时间1,2,3,4。因此,如果您说想要一个新的维“ cases”,那么数据将合并为一个2d数组,如下所示:

times: 1,2,3,4

cases: 1,2

data: 
               time
          1    2    3    4
cases 1:  x1   x2 
      2:            x3   x4

想想netcdf文件是等效的,时间维度必须跨越两个文件中存在的值的范围。合并两个文件并获取(案例:2,时间:124,纬度:241,经度:480)的唯一方法是两个文件的时间,纬度和经度值都相同,即指向完全相同的区域时间延迟空间。

ps:这个问题有些偏离主题,但是如果您只是开始进行新的分析,为什么不改用更高分辨率的ERA-5重新分析,这种新方法现在也可以追溯到1979年(并且最终可以使用)将会进一步扩展),您可以使用python api脚本将其直接下载到桌面上:

https://cds.climate.copernicus.eu/cdsapp#!/search?type=dataset

答案 2 :(得分:0)

谢谢@AdrianTompkins和@jhamman。在您发表评论之后,我意识到由于不同的时间段,使用xarray我确实无法获得想要的东西。

我创建这种数组的主要目的是在一个N-D数组中获取不同事件的所有数据,并且持续时间相同。因此,例如,我可以轻松获得每次(小时,天等)所有事件的复合字段。

我正在尝试做与NCL相同的操作。请参阅下面的NCL代码,该代码对于相同的数据可以正常工作(对我来说):

f = addfiles( (/"eraINTERIM_t2m_201812.nc", "eraINTERIM_t2m_201901.nc"/), "r" )
ListSetType( f, "join" )
temp = f[:]->t2m
printVarSummary( temp )

最终结果是一个具有4维的数组,新数组自动命名为 ncl_join

但是,NCL不遵循时间轴,而是将数组连接起来并向结果的时间轴提供第一个文件的坐标。因此,时间轴变得无用。

但是,正如@AdrianTompkins所说的,时间段是不同的,并且xarray无法连接这样的数据。因此,要在带有xarray的Python中创建这样的数组,我认为唯一的方法是从数组中删除时间坐标。因此,时间维度将只有整数索引。

xarray给出的数组就像@AdrianThompkins在他的小例子中所说的那样。由于它保留所有合并数据的时间坐标,因此与NCL相比,我认为xarray解决方案是正确的。但是,现在,我认为合成的计算(得到上面给出的相同示例)不会像使用NCL那样容易地完成。

在一个小测试中,我使用xarray从合并数组打印两个值

print( da_t2m[ 0, 0, 0, 0 ].values )
print( da_t2m[ 1, 0, 0, 0 ].values )

结果如何

252.11412
nan

在第二种情况下,第一次没有数据,正如预期的那样。

更新:所有答案都帮助我更好地理解了这个问题,因此我不得不在此处添加一个更新,还要感谢@kmuehlbauer的回答,表明他的代码给出了预期的数组。

再次,谢谢大家的帮助!

伴侣