2017-05-10 1 views
2

J'ai un fichier netcdf avec des données en fonction de lon, lat et time. Je voudrais calculer le nombre total d'entrées manquantes dans chaque cellule de la grille additionnée sur la dimension temporelle, de préférence avec CDO ou NCO, donc je n'ai pas besoin d'invoquer R, python etc.Comment calculer le nombre de valeurs manquantes additionnées dans le temps dans un fichier netcdf en bash

Je sais comment obtenir le nombre total des valeurs manquantes

ncap2 -s "nmiss=var.number_miss()" in.nc out.nc 

que je répondais à cette question connexe: count number of missing values in netcdf file - R

et CDO peut me dire le total sommé sur l'espace avec

cdo info in.nc 

mais je ne peux pas calculer comment faire la somme au fil du temps. Existe-t-il un moyen de spécifier la dimension à additionner avec number_miss dans ncap2?

Répondre

1

Nous avons ajouté la fonction manquante() à ncap2 pour résoudre ce problème avec élégance que de sous-officier 4.6.7 (mai 2017). Pour compter les valeurs manquantes dans le temps:

ncap2 -s 'mss_val=three_dmn_var_dbl.missing().ttl($time)' in.nc out.nc 

Ici ncap2 chaînes deux méthodes ensemble, manquantes(), suivi d'un total sur la dimension temporelle. La variable 2D mss_val est dans out.nc. La réponse ci-dessous fait la même chose mais fait la moyenne sur l'espace et rapporte dans le temps (parce que j'ai mal interprété le PO).

réponse Vieux/obsolète:

Il y a deux façons de le faire avec NCO/ncap2, bien que ni est aussi élégant que je le voudrais. Soit appeler assembler la réponse d'un enregistrement à la fois en appelant num_miss() avec un enregistrement à la fois, ou (ma préférence), utilisez la fonction de comparaison booléenne suivie par l'opérateur au total le long des axes de choix:

[email protected]:~$ ncap2 -O -s 'tmp=three_dmn_var_dbl;mss_val=tmp.get_miss();tmp.delete_miss();tmp_bool=(tmp==mss_val);tmp_bool_ttl=tmp_bool.ttl($lon,$lat);print(tmp_bool_ttl);' ~/nco/data/in.nc ~/foo.nc 
tmp_bool_ttl[0]=0 
tmp_bool_ttl[1]=0 
tmp_bool_ttl[2]=0 
tmp_bool_ttl[3]=8 
tmp_bool_ttl[4]=0 
tmp_bool_ttl[5]=0 
tmp_bool_ttl[6]=0 
tmp_bool_ttl[7]=1 
tmp_bool_ttl[8]=0 
tmp_bool_ttl[9]=2 

ou

[email protected]:~$ ncap2 -O -s 'for(rec=0;rec<time.size();rec++){nmiss=three_dmn_var_int(rec,:,:).number_miss();print(nmiss);}' ~/nco/data/in.nc ~/foo.nc 
nmiss = 0 

nmiss = 0 

nmiss = 8 

nmiss = 0 

nmiss = 0 

nmiss = 1 

nmiss = 0 

nmiss = 2 

nmiss = 1 

nmiss = 2 
+0

Merci, upvote car cela me permet de voir la réponse depuis la ligne de commande, mais j'espérais avoir la réponse dans un fichier netcdf 2D. Je suppose que l'ajout d'une fonctionnalité hyperslice à nco, par ex. ncap2 -s "nmiss = var.number_miss (x,:, :) est probablement compliqué? Je ne suis pas très familier avec ncap2 –

+0

Nous avons déjà implémenté et utilisé une syntaxe similaire (par exemple, avg = var.avg ($ lat, $ lon)) à ce que vous suggérez, seulement pour les moyennes, max/min, etc. Je ne sais pas pourquoi nous n'avons pas implémenté cela pour number_miss(). Comme vous l'avez demandé, nous allons le mettre dans la liste TODO :) –

2

Même si vous demandez une autre solution, je voudrais vous montrer qu'il suffit d'une ligne très courte pour trouver la réponse à l'aide de Python. La variable m_data a exactement la même forme qu'une variable avec des valeurs manquantes lues à l'aide du package netCDF4. Avec l'exécution d'une seule commande np.sum avec l'axe correct spécifié, vous avez votre réponse.

import numpy as np 
import matplotlib.pyplot as plt 
import netCDF4 as nc4 

# Generate random data for this experiment. 
data = np.random.rand(365, 64, 128) 

# Masked data, this is how the data is read from NetCDF by the netCDF4 package. 
# For this example, I mask all values less than 0.1. 
m_data = np.ma.masked_array(data, mask=data<0.1) 

# It only takes one operation to find the answer. 
n_values_missing = np.sum(m_data.mask, axis=0) 

# Just a plot of the result. 
plt.figure() 
plt.pcolormesh(n_values_missing) 
plt.colorbar() 
plt.xlabel('lon') 
plt.ylabel('lat') 
plt.show() 

# Save a netCDF file of the results. 
f = nc4.Dataset('test.nc', 'w', format='NETCDF4') 
f.createDimension('lon', 128) 
f.createDimension('lat', 64) 
n_values_missing_nc = f.createVariable('n_values_missing', 'i4', ('lat', 'lon')) 
n_values_missing_nc[:,:] = n_values_missing[:,:] 
f.close() 
+0

Oui, il est concis en python, upvote pour la réponse, je peux avoir à faire cela en python je pense, je peux toujours écrire le champ arrière vers un netcdf Je suppose que –

+0

j'ai ajouté un morceau de code qui vous montre comment enregistrer sur netcdf. – Chiel

+0

Chiel, j'aime votre réponse et elle est compacte et soignée, mais j'ai changé la réponse acceptée à la solution NCO mise à jour car elle me permet de faire l'opération à partir de la ligne de commande. Les deux réponses sont excellentes. –