【问题标题】:Merging multiple Netcdf files according to the vertical level根据垂直级别合并多个Netcdf文件
【发布时间】:2021-01-06 20:49:52
【问题描述】:

我有 34 个 netCDF (nc) 文件,其中包含纬度、经度和每个文件中的数据。每个文件名都包含一个对应于 hPa 压力级别的数字(从 1 到 34 开始,对应的压力级别从(1000 hPa 到 0.4 hPa)。我想将所有文件加入到一个具有此垂直级别尺寸信息的单个 nc 文件中。

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

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

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

样本数据在这里https://www.dropbox.com/sh/linfn0721ze3j1f/AACwxTsQVNyiE7mF_gRbpRfra?dl=0

【问题讨论】:

  • 请问,文件本身没有记录压力等级的数据条目(维度、变量或全局属性)吗?即想从文件名中获取压力并在合并文件中添加一个新维度?
  • @AdrianTompkins 是的,该文件不包含压力级别信息,它只包含纬度、经度和数据。但它在文件名中给出了压力水平信息(比如1代表表面水平1000 hPa,2代表975 hPa这样的)。
  • ps:从您对 Robert Wiilson 的回复来看,您似乎并没有依赖于 python 解决方案,但很高兴有一个 nco/cdo 替代方案。如果是这样,我可能会编辑问题以反映这一点,因为当使用指定的某种语言提出问题时,有些人会投反对票,然后人们会用另一种语言上传答案。
  • @AdrianTompkins 非常感谢您的建议和编辑。谢谢。

标签: python netcdf python-xarray nco cdo-climate


【解决方案1】:

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

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

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

【讨论】:

  • 感谢@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 但是当我交叉检查 Grads 中的数据时,当我设置 z 1 时它显示 0.4 hPa 数据。同样,“set z 34”代表 1000 hPa 数据。这使我的分析变得困难,因为通常 z 1 代表 1000 hPa。我不明白原因,因为它专门为 1000 hPa 数据分配 -setlevel 1000。可能与 CDO -setlevel 保存相矛盾?我不确定
【解决方案2】:

这是一个 BASH 脚本,它定义了一个压力级别列表(查看 cmets),然后主力是 ncap2,用于为每个文件添加一个名为“级别”的维度,然后定义一个变量“水平”与定义的压力值。然后我使用 ncatted 添加属性以确保完整性,例如压力单位。

cdo 然后在最后用于合并文件(也可以使用 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" as per the comments on this post 中删除属性,我不确定为什么,所以这意味着您需要使用 ncatted 读取这些属性。 This answer here from Charlie Zender was also helpful 来构造这段代码。

【讨论】:

  • 这可行,但有一个问题,我与 Panoply 和 GrADS 进行了交叉检查。当我尝试这种方法时,我可以在输出文件中看到的垂直级别序列如下; 1000 hPa 文件(如 data1.nc)然后是 600 hPa(如 data11.nc),然后是 550 hPa(如 data12.nc)。上述方法中合并数据的for循环我认为不是顺序的。顺便说一句,非常感谢您提供的优质脚本
  • 从这个和你给罗伯特和查理的答案,我认为你的文件不是按压力顺序排列的。循环每次将 i 增加 1,因此请考虑按 file1、file2、...文件 N 顺序排列的文件(您可以在循环内放置 echo $file 和 echo ${p_levs[$i]} 进行打印文件名和压力用于查看对应的名称和压力是什么)并且压力也是有序的,它不像使用通配符命令,例如 ls file* - 仔细检查各个文件以确保它们是按压力顺序。
【解决方案3】:

使用 NCO 的另一种方法是首先将级别与ncecat 结合起来,例如,

ncecat -u level in*.nc out1.nc

然后用ncap2添加关卡坐标,例如,

ncap2 -O -s 'level[$level]={1000, 975, ... 0.4}' out1.nc out2.nc

然后添加带有ncatted 的属性,如 Adrian 所示。

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

祝你好运, 查理

【讨论】:

  • 查理总是设法写出比我的短 4 倍、整洁 10 倍的 nco 解决方案;-)
  • 由于某些原因,ncecat -u level data*.nc out1.nc 将 data10.nc 作为第一个文件。因此,它将 650 hPa 数据而不是 1000 hPa 数据(如 data1.nc 中的数据)作为第一级。
  • 通配符运算符(星号)按字母顺序展开文件。 data10.nc 必须在 data1.nc 之前,或类似的东西。为您的文件命名,以便它们按正确的字母顺序排序,或者消除通配符并手动将文件按正确的顺序放置在命令行上。
猜你喜欢
  • 2018-10-10
  • 2020-07-05
  • 2013-06-28
  • 2018-04-23
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 2015-05-11
相关资源
最近更新 更多