2016-12-20 2 views
0

J'ai un fichier netcdf avec environ 100 timesteps sur une grille avec une variable, qui est accumulée au cours des timesteps. Je suis maintenant intéressé par le calcul de la contribution de chaque pas de temps à la valeur de la variable (c'est-à-dire la différence de pas de temps consécutifs).Meilleure dispersion de timesteps Netcdf accumulés avec CDO

Actuellement, j'utiliser la séquence suivante:

  1. Pour extraire chaque timestep seul dans un nouveau fichier que j'utilise cdo seltimestep,$i ...,
  2. calculer chaque différence dans un nouveau fichier avec cdo sub $i ${i-1} ...
  3. et fusionner ces nouveaux fichiers à la fin avec cdo mergetime ... dans un seul fichier de résultats.

Cela me semble être très lourd et pas idéal en ce qui concerne la performance. En raison de la quantité de timesteps je ne peux pas utiliser un pipeline cdo et j'ai besoin de créer beaucoup de fichiers en attendant.

Y at-il une meilleure solution pour disperser une variable accumulée avec cdo (ou quelque chose d'autre comme nco/ncl?)

+0

êtes-vous uniquement intéressé par les solutions 'cdo'? J'ai un 1-liner en Python qui le fera pour vous. – jhamman

+0

@jhamman Je suis très intéressé de voir ce 1-liner, je ne suis pas limité à 'cdo' –

Répondre

1

numpy's diff calcule la différence d'entrées consécutives.

Je suppose que vous avez une variable multi-dimension dans votre fichier, alors voici un exemple générique de la façon de le faire:

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

Y at-il un moyen facile d'écraser les anciennes valeurs dans le fichier existant ou écrire les nouvelles valeurs à une copie du fichier? Je n'ai jamais travaillé avec Python NetCDF4 avant ... –

+0

Merci d'avoir signalé la faute de frappe de 'variable'! Et j'ai mis à jour ma réponse pour montrer comment écrire la nouvelle variable dans un nouveau fichier netcdf. Pour plus d'exemples, consultez les documents ici: http://unidata.github.io/netcdf4-python/ – N1B4

+0

Je suis impressionné à quel point cette version est beaucoup plus rapide par rapport à ma solution cdo –

1

xarray est mon outil de choix pour ce genre de chose:

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

J'aime cette solution, mais au moins pour mon cas d'utilisation xarray est plus lent comparé à numpy –