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

爷,独闯天下 提交于 2020-02-25 04:40:29

问题


I have a netcdf-file with about 100 timesteps on a grid with one variable, which is accumulated over the timesteps. I am now interested in calculating the contribution of each timestep to the variable's value (i.e. 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 ...,
  2. calculate each difference into a new file with cdo sub $i ${i-1} ...
  3. and merge those new files in the end with cdo mergetime ... into one single result file.

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.

Is there one better solution to convert an accumulated variable to timestep values with cdo (or something else like nco/ncl?)


回答1:


numpy's diff computes the difference of consecutive entries.

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()



回答2:


xarray is my tool of choice for this sort of thing:

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')



回答3:


If you want a CDO based solution there is a shorter way that avoids loops and writing out a lot of files:

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:

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


来源:https://stackoverflow.com/questions/41244064/converting-an-accumulated-variable-to-timestep-values-in-a-netcdf-file-with-cdo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!