使用xarray python组合空间netcdf文件
Posted
技术标签:
【中文标题】使用xarray python组合空间netcdf文件【英文标题】:combining spatial netcdf files using xarray python 【发布时间】:2018-12-31 09:39:18 【问题描述】:有没有办法将 2 个或多个具有相同时间维度但空间域不同的 netCDF 文件合并到一个 netCDF 文件中?空间域由纬度和经度坐标指定?在 xarray concat、merge 等的文档中,他们说它们使用单一维度
【问题讨论】:
您能否描述一下您的数据的外观以及您希望它最终的外观?它看起来像 T, Lat1, Lon1, Lat2, Lon2, Lat3, Lon3 这基本上意味着您正在时间维度上进行连接吗? 【参考方案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【参考方案2】:我对您的问题的理解是,您想要打开多个 netcdf 文件,其中包含数据的不同空间部分,其中整个数据集已沿 lat
和 lon
分解。
如果是这样,恐怕xarray目前不支持这个,我在xarray github上询问了完全相同的问题here.
SO here. 上也有人问过同样的问题,那里提到的 concat
解决方案会起作用。
就我而言,然后我想将连接的数据集保存到一个新的 netcdf 文件中,但使用此方法最终将所有数据一次加载到内存中。为了解决这个问题,我最终不得不使用 netcdf python 库在较低级别解决这个问题,但这需要付出很多努力。
【讨论】:
感谢@Thomas,如果您可以分享代码,很高兴接受您的回答 @user308827 我已经为您提供了here 的代码,但它有 300 行代码,在某种程度上与我正在做的事情有关。很多代码实际上是为了智能地决定 .nc 文件中的哪些字段应该保存在哪里。我也不认为这是解决问题的特别好方法,但目前它对我有用。如果您想就更好的解决方案进行合作,那么我会对此持开放态度。 如果您需要任何解释,请告诉我! 还有人刚刚在 xarray github 上发布了issue thread 的第三个解决方案。 @user308827 现在有更好的方法来解决这个问题 - 请参阅我的新答案【参考方案3】:xarray 现在支持直接通过open_mfdataset
进行多维连接。
关于沿多个维度组合数据的文档是here,但由于您的问题与this one 非常相似,我将在此处复制我的答案的关键部分:
您有一个 2D 连接问题:您需要排列数据集,以便当沿 x 和 y 连接时,它们会形成一个更大的数据集,该数据集也具有 x 和 y 维度。
只要len(x)
在每个文件中都相同,len(y)
在每个文件中都相同,理论上您应该能够以一种或两种不同的方式做到这一点。
1) 使用combine='nested'
您可以手动指定需要它们连接的顺序。xarray 允许您通过将数据集作为网格传递来执行此操作,指定为嵌套列表。在您的情况下,如果我们有 4 个文件(名为 [upper_left、upper_right、lower_left、lower_right]),我们会像这样组合它们:
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'
选项的用途,但不幸的是,它需要一维坐标(也称为维坐标)来排列数据。如果您的文件没有这些文件,打印输出将显示Dimensions without coordinates: x, y
)。
如果您可以先向文件添加一维坐标,则可以使用combine='by_coords'
,然后您可以按任意顺序传递所有文件的列表,即
ds = open_mfdataset([file1, file2, ...], combine='by_coords')
但否则你将不得不使用combine='nested'
。
【讨论】:
@user308827 现在有更好的方法来解决这个问题 谢谢@Thomas,but unfortunately, it requires 1-dimensional coordinates (also known as dimensional coordinates) to arrange the data
是什么意思?这是否意味着它不适用于二维数据?
您可以合并二维数据,但您需要使用combine='nested'
选项并准确告诉它数据集需要的顺序。我的意思是您可以t 以全自动方式(即 combine='by_coords')在数据集中没有一维坐标。
如果我有不同的纬度和经度尺寸并且有不同的索引,我有什么选择 ;)?
@tillKadabra 我不完全清楚你的意思,但 xarray 只能帮助你将一组相等(纬度,经度)尺寸的矩形并排拼接在一起,或者堆叠一组通过创建一个新维度,将相等(纬度、经度)维度的矩形相互叠加。你不能加入不均匀的数据集网格,或者有所谓的参差不齐的数组。以上是关于使用xarray python组合空间netcdf文件的主要内容,如果未能解决你的问题,请参考以下文章