Python 根据垂直级别合并多个Netcdf文件

Python 根据垂直级别合并多个Netcdf文件,python,netcdf,python-xarray,nco,cdo-climate,Python,Netcdf,Python Xarray,Nco,Cdo Climate,我有34个netCDF(nc)文件,其中包含纬度、经度和每个文件中的数据。每个文件名都包含一个数字,该数字对应于hPa中的压力级别(从1到34开始,对应于从(1000 hPa到0.4 hPa)的各个压力级别)。我希望使用此垂直级别维度信息将所有文件合并到一个nc文件中 我尝试使用xarray open_mfdataset读取整个文件,但我无法使用level维度,因为它不在文件中 import xarray as xr ds = xr.open_mfdataset('/media/MediaCen

我有34个netCDF(nc)文件,其中包含纬度、经度和每个文件中的数据。每个文件名都包含一个数字,该数字对应于hPa中的压力级别(从1到34开始,对应于从(1000 hPa到0.4 hPa)的各个压力级别)。我希望使用此垂直级别维度信息将所有文件合并到一个nc文件中

我尝试使用xarray open_mfdataset读取整个文件,但我无法使用level维度,因为它不在文件中

import xarray as xr
ds = xr.open_mfdataset('/media/MediaCentre/Dataset/d9/data*.nc',concat_dim='level')
这些文件在全局属性中没有关于压力的任何信息。它们的名称顺序为:data1.nc、data2.nc、…dataN.nc,并对应于以下压力级别(hPa): 1000 975 950 925 900 850 800 750 700 650 600 550 500 450 400 350 300*250 200 150 100 70 50 40 30 20 15 10 7 5 3 2 1 0.4

如何使用pythonxarray或cdo/nco将它们合并在一起


示例数据在这里

使用CDO可能更容易做到这一点。以下内容将合并您提供的两个示例文件:

cdo -L -merge -setlevel,0.4 data1.nc -setlevel,1 data2.nc merged.nc

只需修改上面的内容就可以处理所有文件。

这是一个BASH脚本,它定义了一个压力级别列表(查看注释),然后是工作区,用于向每个文件添加一个称为“级别”的维度,然后定义一个变量“级别”定义压力值后,我使用NCATT添加完整性属性,如压力单位

import xarray as xr
ds = xr.open_mfdataset('/media/MediaCentre/Dataset/d9/data*.nc',concat_dim='level')
然后在结尾使用合并文件(也可以使用nco)。这里的示例仅合并两个文件,但您可以合并所有文件

#!/bin/bash

# define pressure levels here, start, inc, end or just a list
# this is important to get right, the number of files processed
# depends on this list, here I only process 2 files,
# data1.nc = 1000hPa, data2.nc=975 hPa

# this was my test merging two files, can use seq if p levs are regular
# p_levs=($(seq 1000 -25 975))

# this is the full code:
p_levs=(1000 975 950 925 900 850 800 750 700 650 600 550 500 450 400 350 300 250 200 150 100 70 50 40 30 20 15 10 7 5 3 2 1 0.4)
    
# loop over the pressure levels, data1.nc-> first pressure level, data2-> second etc
for i in ${!p_levs[@]} ; do
    infile=data$(expr $i + 1).nc # nc filename

    # add a level dimension and define variable with pressure level:
    ncap2 -O -s 'defdim("level",1);q[level,lat,lon]=q;level=array('${p_levs[$i]}',10,$level)' $infile tmp${i}_$infile

    # put in attributes for the new level variable:
    ncatted -h -a units,"level",o,c,"hPa" tmp${i}_$infile
    ncatted -h -a long_name,"level",o,c,"Pressure level" tmp${i}_$infile
done

# merge the files:
cdo merge tmp*.nc merged.nc

# clean up tmp files at end 
rm -f tmp*.nc 
我使用p_levs=“1000 975”对其进行了测试,它合并了前两个文件data1.nc和data2.nc,没有问题,结果文件在ncview中打开正常,看起来很好


注意:出于某种原因,ncap2正在从“q”中删除属性,我不确定原因,因此这意味着您需要读取带有NCATT的属性。要构建此代码。

使用NCO的不同方法将首先将级别与相结合,例如

然后添加标高坐标,例如

然后添加属性,如Adrian所示

ncatted <Adrian's example> out2.nc out3.nc

ncatted Thank@robert wilson,实际上我试过CDO,它是在水平面(维度)上叠加的表面。这就是我试图处理xarray的原因。@rober wilson实际上CDO以这种方式工作得很好,
CDO-L-merge-setlevel,1000 data1.nc-setlevel,975 data2.nc……-setlevel,1 data33.nc-setlevel,0.4 data34.nc-merged.nc
,但当我以梯度交叉检查数据时,当我设置z1时,它显示0.4 hPa数据。类似地,“set z34”represents 1000 hPa数据。这使我的分析变得困难,因为通常z 1代表1000 hPa。但我不知道原因,因为它专门为1000 hPa数据分配了-setlevel 1000。这可能与CDO-setlevel保存相矛盾?我不确定是否可以问一下,在文件本身中没有数据输入(维度、变量或全局属性)记录压力级别后?即,希望从文件名中获取压力并在合并文件中添加新维度?@AdrianTompkins是的,该文件不包含压力级别信息,只包含纬度、经度和数据。但文件名中提供了压力级别信息(如1表示地面标高1000百帕,如2表示975百帕).ps:从您对Robert Wiilson的回复来看,您似乎不喜欢python解决方案,但很高兴有一个nco/cdo替代方案。如果是这样,我可能会编辑这个问题来反映这一点,因为当用指定的语言提问时,有些人会投反对票,然后人们会用另一种语言上传答案。@AdrianTompkins我会这样做非常感谢您的建议和编辑。谢谢。Charlie总是设法编写一个nco解决方案,它比我的短4倍,整洁10倍;-)出于某些原因,
ncecat-u级别数据*.nc out1.nc
将data10.nc作为第一个文件。因此,它将650 hPa数据作为第一个级别,而不是1000 hPa数据(如data1.nc中所示).通配符运算符(星号)按字母顺序展开文件。data10.nc必须在data1.nc之前,或类似的名称。命名文件,使其按正确的字母顺序排序,或删除通配符,并手动将文件按正确的顺序放置在命令行上。这样做有效,但有一个问题,我与Panoply和GrADS进行了交叉检查。当我尝试此操作时方法,按照我在ouyput文件中看到的顺序垂直水平,如下所示:1000 hPa文件(如data1.nc中所示),然后是600 hPa(如data11.nc中所示),然后是550 hPa(如data12.nc中所示)在上面的方法中,for循环合并数据并不是按顺序排序的。非常感谢你的伟大的脚本,从这个方法和你给罗伯特和查利的答案中,然后我认为你的文件不是按压力顺序排序的。循环每次增加了1,所以在文件FIL1、FILE2、FIL的顺序中考虑文件。e N,(您可以在循环中放入echo$文件和echo${p_levs[$i]}以打印文件名和压力,以查看使用的相应名称和压力)并且压力也是有序的,这与使用通配符顺序(如ls file*)不同-仔细检查各个文件,确保它们是有序的。
ncatted <Adrian's example> out2.nc out3.nc