python netcdf: создание копии всех переменных и атрибутов, кроме одного
Мне нужно обработать одну переменную в файле netcdf, который фактически содержит много атрибутов и переменных. Я думаю, что невозможно обновить файл netcdf (см. вопрос Как удалить переменную в Scientific.ИО.NetCDF.NetCDFFile?)
мой подход следующий:
- сделать переменную для обработки из исходного файла переменная
- скопируйте все данные из исходного netcdf, но обработанные переменная для конечного файла
- скопируйте обработанную переменную в конечный файл
моя проблема заключается в том, чтобы кодировать Шаг 3. Я начал со следующего:--4-->
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
Как я могу сохранить все данные и атрибут в полном коде без необходимости перестраивать всю структуру данных?
5 ответов
вот что я только что использовал и работал. ответ @arne обновлен для Python 3, а также включает копирование атрибутов переменных:
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__)
если вы просто хотите скопировать файл выбираем переменные, nccopy
- отличный инструмент, представленный @rewfuss.
вот для Python (и более гибкие) решения с python-netcdf4
. Это позволяет открыть его для обработки и других вычислений перед записью в файл.
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][:]
это не учитывает переменные атрибуты, такие как fill_values
. Вы можете сделать это легко, следуя документации.
как быть осторожно, файлы netCDF4 после записи / создания таким образом не могут быть отменены. В тот момент, когда вы изменяете переменную, она записывается в файл в конце инструкции with, или если вы вызываете .close()
на Dataset
.
конечно, если вы хотите обработать переменные перед их написанием, вы должны быть осторожны с тем, какие измерения создавать. В новом файле никогда не записывайте переменные без их создания. Кроме того, никогда не создавайте переменные без определенных измерений, как отметил в python-netcdf4
's документация.
утилита nccopy в C netCDF версии 4.3.0 и более поздних версиях включает в себя возможность перечислить, какие переменные должны быть скопированы (вместе с их атрибутами). К сожалению, он не включает опцию, для которой переменные следует исключить, что вам и нужно.
однако, если список (разделенных запятыми) переменных, которые должны быть включены, не заставляет командную строку nccopy превышать системные ограничения, это будет работать. Существует два варианта этой опции:
nccopy -v var1,var2,...,varn input.nc output.nc
nccopy -V var1,var2,...,varn input.nc output.nc
в первый (-V) включает все определения переменных, но только данные для именованных переменных. Второй (- V)не включает определения или данные для неназванных переменных.
этот ответ основан на ответе Ксавье Хо (https://stackoverflow.com/a/32002401/7666), но с исправлениями мне нужно было завершить его:
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][:]
Я знаю, это старый вопрос, но в качестве альтернативы, вы можете использовать библиотеку в формате netcdf и 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