简体   繁体   English

使用 CDO 将累积变量转换为 netcdf 文件中的时间步长值

[英]converting an accumulated variable to timestep values in a netcdf file with CDO

I have a netcdf-file with about 100 timesteps on a grid with one variable, which is accumulated over the timesteps.我在一个带有一个变量的网格上有一个大约 100 个时间步长的 netcdf 文件,它是在时间步长上累积的。 I am now interested in calculating the contribution of each timestep to the variable's value (ie the difference of consecutive timesteps).我现在有兴趣计算每个时间步长对变量值的贡献(即连续时间步长的差异)。

Currently I use the following sequence:目前我使用以下顺序:

  1. To extract every single timestep into a new file I use cdo seltimestep,$i ... ,要将每个时间步提取到一个新文件中,我使用cdo seltimestep,$i ...
  2. calculate each difference into a new file with cdo sub $i ${i-1} ...使用cdo sub $i ${i-1} ...每个差异计算到一个新文件中cdo sub $i ${i-1} ...
  3. and merge those new files in the end with cdo mergetime ... into one single result file.最后使用cdo mergetime ...将这些新文件合并为一个结果文件。

That seems to me to be very cumbersome and not ideal regarding to performance.在我看来,这非常麻烦,而且在性能方面并不理想。 Because of the amount of timesteps I cannot use a cdo pipeline and need to create many files in the meantime therefore.由于时间步长,我无法使用 cdo 管道,因此需要同时创建许多文件。

Is there one better solution to convert an accumulated variable to timestep values with cdo (or something else like nco/ncl?)有没有更好的解决方案可以使用 cdo(或其他类似 nco/ncl 的方法)将累积变量转换为时间步长值?

numpy's diff computes the difference of consecutive entries. numpy 的 diff计算连续条目的差异。

I suspect you have a multi-dimension variable in your file, so here is a generic example of how to do it:我怀疑您的文件中有一个多维变量,所以这里有一个通用的例子:

import netCDF4
import numpy as np

ncfile = netCDF4.Dataset('./myfile.nc', 'r')
var = ncfile.variables['variable'][:,:,:] # [time x lat x lon]

# Differences with a step of 1 along the 'time' axis (0) 
var_diff = np.diff(var, n=1, axis=0) 
ncfile.close()

# Write out the new variable to a new file     
ntim, nlat, nlon = np.shape(var_diff)

ncfile_out = netCDF4.Dataset('./outfile.nc', 'w')
ncfile_out.createDimension('time', ntim)
ncfile_out.createDimension('lat', nlat)
ncfile_out.createDimension('lon', nlon)
var_out = ncfile_out.createVariable('variable', 'f4', ('time', 'lat', 'lon',))
var_out[:,:,:] = var_diff[:,:,:]
ncfile_out.close()

xarray is my tool of choice for this sort of thing: xarray是我处理这类事情的首选工具:

import xarray as xr

# Open the netCDF file
ds = xr.open_dataset('./myfile.nc')

# Take the diff along the time dimension
ds['new_variable'] = ds['variable'].diff(dim='time')

# Write a new file
ds.to_netcdf('outfile.nc')

If you want a CDO based solution there is a shorter way that avoids loops and writing out a lot of files:如果你想要一个基于 CDO 的解决方案,有一种更短的方法可以避免循环和写出大量文件:

file=your_file_name.nc # just to keep the code shorter in the following :-)

# calculate number of steps in the file:
nstep=`cdo -s ntime $file`

# do difference between steps 2:n and steps 1:(n-1)
cdo sub -seltimestep,2/$nstep $file -seltimestep,1/`expr $nstep - 1` $file  diff.nc

If you are not worried about the first timestep you can stop here, otherwise you need to extract it and paste it on the front of the file:如果你不担心第一个timestep你可以停在这里,否则你需要把它解压并粘贴到文件的前面:

cdo mergetime -seltimestep,1 $file diff.nc output.nc 

you can attempt to pipe the whole thing as a oneliner although it is a bit messy (and I do find that over ambitious piping can lead to bus errors)!您可以尝试将整个事情作为单行管道进行管道传输,尽管它有点凌乱(而且我确实发现过于雄心勃勃的管道可能会导致总线错误)!

cdo mergetime -seltimestep,1 $file -sub -seltimestep,2/$nstep $file -seltimestep,1/`expr $nstep - 1` $file output.nc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM