使用Xarray Python组合空间NetCDF文件

17

有没有一种方法将具有相同时间维度但不同空间域的2个或多个netCDF文件合并为单个netCDF文件? 空间域由纬度和经度坐标指定。 在xarray concat,merge等文档中,它们说它们只能处理单个维度。


你能描述一下你的数据长什么样子,以及最终想要它看起来是什么样子吗?最终它会像T、Lat1、Lon1、Lat2、Lon2、Lat3、Lon3这样吗?这基本上意味着你正在时间维度上进行连接操作? - doodhwala
3个回答

6
我的理解是您想要打开多个包含数据不同空间部分的netcdf文件,其中整个数据集沿着latlon被拆分。
如果是这样的话,很遗憾xarray目前不支持此功能,我在xarray的github上提出了完全相同的问题here. 在SO上也有关于这个问题的讨论here.其中提到的concat解决方案可以解决这个问题。
在我的情况下,我希望将连接后的数据集保存到一个新的netcdf文件中,但使用这种方法会一次性将所有数据加载到内存中。为了避免这种情况,我最终不得不使用netcdf python库在较低层次上解决这个问题,但需要付出大量努力。

1
感谢@Thomas,如果您能分享代码,我很乐意接受您的答案。 - user308827
1
@user308827,我已经在这里放置了代码,但它有300行代码,有些特定于我正在做的事情。很多代码实际上是为了智能地决定应该将.nc文件中的哪些字段保存在哪里。我也不认为这是解决问题的特别好的方法,但目前它对我有效。如果你想合作找到更好的解决方案,我很乐意。 - ThomasNicholas
1
如果您需要任何解释,请告诉我! - ThomasNicholas
2
同时,有人在xarray的Github上的问题讨论中发布了第三个解决方案。 - ThomasNicholas
1
@user308827,现在有一种更好的解决方法 - 请查看我的新答案。 - ThomasNicholas

5

xarray现在通过open_mfdataset直接支持多维连接。

有关沿多个维度组合数据的文档在这里,但是由于您的问题与此问题非常相似,因此我将在此处复制我的答案的关键部分:


您有一个二维连接问题:您需要安排数据集,在沿x和y连接时,它们构成一个更大的数据集,该数据集还具有x和y两个维度。

只要每个文件中的len(x)都相同,并且每个文件中的len(y)都相同,理论上您应该可以以一种或两种不同的方式完成此操作。

1)使用combine='nested'

您可以手动指定需要连接的顺序。 xarray允许您通过传递作为嵌套列表的网格来执行此操作。 在您的情况下,如果我们有4个文件(命名为[左上,右上,左下,右下]),我们将按以下方式将它们组合:

from xarray import open_mfdataset

grid = [[upper_left, upper_right], 
        [lower_left, lower_right]]

ds = open_mfdataset(grid, concat_dim=['x', 'y'], combine='nested')

我们需要告诉open_mfdataset数据的行和列对应哪些维度,从而让它知道在哪些维度上进行数据串联。这就是为什么我们需要传递concat_dim=['x', 'y']

2) 使用combine='by_coords'

但是你的数据已经包含坐标信息了 - xarray不能使用这些信息来正确排列数据集吗?这就是combine='by_coords'选项的作用,但不幸的是,它需要1维坐标(也称为dimensional coordinates)来排列数据。如果你的文件没有这些坐标,则输出将显示Dimensions without coordinates: x, y

如果你能先给你的文件添加1维坐标,那么你就可以使用combine='by_coords',然后只需要以任意顺序传递所有文件的列表即可,例如:

ds = open_mfdataset([file1, file2, ...], combine='by_coords')

但是否则你将不得不使用combine ='nested'


@user308827,现在有一种更好的方法来解决这个问题。 - ThomasNicholas
谢谢@Thomas,你说的“但不幸的是,它需要一维坐标(也称为一维坐标)来排列数据”是什么意思?这是否意味着它不能用于二维数据? - user308827
你可以组合2D数据,但需要使用combine='nested'选项,并告诉它数据集的确切顺序。我的意思是,如果你的数据集中没有1D坐标,则不能使用完全自动化的方式(即combine='by_coords')完成该操作。 - ThomasNicholas
如果我的纬度和经度有不同的尺寸大小,同时索引也不同,那我有哪些选项? - till Kadabra
1
@tillKadabra 我不是完全清楚你的意思,但是 xarray 只能帮助你将一组相等(纬度、经度)维度的矩形并排拼接在一起,或者通过创建新的维度将一组相等(纬度、经度)维度的矩形堆叠在一起。你不能连接不均匀的数据集网格,或者所谓的不规则数组。 - ThomasNicholas

1
我不知道在Python(或R、FORTRAN)中有一种“自动化”的方法来完成这个任务,只能手动读取文件并将其存储到一个更大的数组中,然后将该数组写入新的netcdf文件,但是使用CDO可以通过命令行更加“自动化”地完成此任务。
如果您定义了一个包含两个(或多个)文件区域的域描述文件grid.txt:
gridtype = lonlat
gridsize = 420
xname = lon
xlongname = longitude
xunits = degrees east
yname = lat
ylongname = latitude
yunits = degrees north
xsize = 21
ysize = 20
xfirst = -11.0
xinc = 1
yfirst = -20.0
yinc = 1

然后您需要将第一个文件 file1.nc "扩展" 到更大的域中,然后合并两个 netcdf 文件的内容:

cdo expand,grid.txt file1.nc large.nc
cdo mergegrid large.nc file1.nc merge1.nc
cdo mergegrid merge1.nc file2.nc final_merge.nc 

我在这里找到了一个解决方案:https://code.mpimet.mpg.de/boards/1/topics/26,当我需要合并2或3个文件时,我使用它。然而,当我需要合并数百个包含每行数据的一维纬度的文件时,我编写了一个手动程序(在我的情况下是用R编写的)。


谢谢@Adrian!我喜欢cdo,尽管它只能在Linux / Mac上使用。 - user308827

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