Python NetCdf: hacer una copia de todas las variables y atributos, pero uno

Necesito procesar una sola variable en un archivo netcdf que en realidad contiene muchos atributos y variables. Creo que no es posible actualizar un archivo netcdf (ver pregunta ¿Cómo eliminar una variable en un Scientific.IO.NetCDF.NetCDFFile? )

Mi enfoque es el siguiente:

  1. obtener la variable para procesar desde el archivo original
  2. procesar la variable
  3. Copie todos los datos del netcdf original, PERO la variable procesada al archivo final
  4. Copia la variable procesada al archivo final.

Mi problema es codificar el paso 3. Comencé con lo siguiente:

def processing(infile, variable, outfile): data = fileH.variables[variable][:] # do processing on data... # and now save the result fileH = NetCDFFile(infile, mode="r") outfile = NetCDFFile(outfile, mode='w') # build a list of variables without the processed variable listOfVariables = list( itertools.ifilter( lamdba x:x!=variable , fileH.variables.keys() ) ) for ivar in listOfVariables: # here I need to write each variable and each attribute 

¿Cómo puedo guardar todos los datos y atributos en un puñado de código sin tener que reconstruir toda una estructura de datos?

Esto es lo que acabo de usar y funcionó. La respuesta de @arne se actualizó para Python 3 y también para copiar atributos de variables:

 import netCDF4 as nc toexclude = ['ExcludeVar1', 'ExcludeVar2'] with netCDF4.Dataset("in.nc") as src, netCDF4.Dataset("out.nc", "w") as dst: # copy global attributes all at once via dictionary dst.setncatts(src.__dict__) # copy dimensions for name, dimension in src.dimensions.items(): dst.createDimension( name, (len(dimension) if not dimension.isunlimited() else None)) # copy all file data except for the excluded for name, variable in src.variables.items(): if name not in toexclude: x = dst.createVariable(name, variable.datatype, variable.dimensions) dst[name][:] = src[name][:] # copy variable attributes all at once via dictionary dst[name].setncatts(src[name].__dict__) 

Si solo desea copiar las variables de selección de archivos, nccopy es una excelente herramienta tal como lo presentó @rewfuss.

Aquí hay una solución Pythonic (y más flexible) con python-netcdf4 . Esto le permite abrirlo para procesar y otros cálculos antes de escribir en el archivo.

 with netCDF4.Dataset(file1) as src, netCDF4.Dataset(file2) as dst: for name, dimension in src.dimensions.iteritems(): dst.createDimension(name, len(dimension) if not dimension.isunlimited() else None) for name, variable in src.variables.iteritems(): # take out the variable you don't want if name == 'some_variable': continue x = dst.createVariable(name, variable.datatype, variable.dimensions) dst.variables[x][:] = src.variables[x][:] 

Esto no tiene en cuenta los atributos de las variables, como los fill_values . Puedes hacerlo fácilmente siguiendo la documentación.

Tenga cuidado, los archivos netCDF4 una vez escritos / creados de esta manera no se pueden deshacer. En el momento en que modifica la variable, se escribe en el archivo al final de la statement, o si llama a .close() en el Dataset .

Por supuesto, si desea procesar las variables antes de escribirlas, debe tener cuidado sobre qué dimensiones crear. En un archivo nuevo, nunca escriba en variables sin crearlas. Además, nunca cree variables sin tener dimensiones definidas, como se indica en la documentación de python-netcdf4 .

La utilidad nccopy en C netCDF versiones 4.3.0 y posteriores incluye una opción para enumerar qué variables se copiarán (junto con sus atributos). Desafortunadamente, no incluye una opción para qué variables excluir, que es lo que necesita.

Sin embargo, si la lista de variables (delimitadas por comas) que se incluye no hace que la línea de comandos de nccopy exceda los límites del sistema, esto funcionaría. Hay dos variantes para esta opción:

 nccopy -v var1,var2,...,varn input.nc output.nc nccopy -V var1,var2,...,varn input.nc output.nc 

La primera (-v) incluye todas las definiciones de variables, pero solo datos para las variables nombradas. El segundo (-V) no incluye definiciones o datos para variables sin nombre.

Esta respuesta se basa en la de Xavier Ho ( https://stackoverflow.com/a/32002401/7666 ), pero con las correcciones que necesitaba para completarla:

 import netCDF4 as nc import numpy as np toexclude = ["TO_REMOVE"] with nc.Dataset("orig.nc") as src, nc.Dataset("filtered.nc", "w") as dst: # copy attributes for name in src.ncattrs(): dst.setncattr(name, src.getncattr(name)) # copy dimensions for name, dimension in src.dimensions.iteritems(): dst.createDimension( name, (len(dimension) if not dimension.isunlimited else None)) # copy all file data except for the excluded for name, variable in src.variables.iteritems(): if name not in toexclude: x = dst.createVariable(name, variable.datatype, variable.dimensions) dst.variables[name][:] = src.variables[name][:] 

Sé que esta es una pregunta antigua, pero como alternativa, puede usar la biblioteca netcdf y shutil :

 import shutil from netcdf import netcdf as nc def processing(infile, variable, outfile): shutil.copyfile(infile, outfile) with nc.loader(infile) as in_root, nc.loader(outfile) as out_root: data = nc.getvar(in_root, variable) # do your processing with data and save them as memory "values"... values = data[:] * 3 new_var = nc.getvar(out_root, variable, source=data) new_var[:] = values