Python: замена значений в файле netcdf с помощью netCDF4

У меня есть файл netcdf с несколькими значениями ‹0. Я хотел бы заменить их все одним значением (скажем, -1). Как мне это сделать с помощью netCDF4? Я читаю в файле так:

import netCDF4

dset      = netCDF4.Dataset('test.nc')
dset[dset.variables['var'] < 0] = -1

person user308827    schedule 06.08.2015    source источник


Ответы (4)


Если вы хотите сохранить данные в объекте переменной netCDF, это должно сработать:

import netCDF4

dset = netCDF4.Dataset('test.nc', 'r+')

dset['var'][:][dset['var'][:] < 0] = -1

dset.close() # if you want to write the variable back to disk

Если вы не хотите записывать обратно на диск, просто получите массив numpy и срежьте / назначьте ему:

data = dset['sea_ice_cover'][:]  # data is a numpy array
data[data < 0] = -1
person jhamman    schedule 06.08.2015
comment
Будьте осторожны, если переменная сжимается с помощью scale_factor и add_offset. В этом случае только значение, указанное атрибутом fill_value, будет записано непосредственно в файл. Любое другое значение будет автоматически сжато. - person sfinkens; 02.08.2017

Для меня предыдущий ответ не работает, я решил его:

dset = netCDF4.Dataset('test.nc','r+')
dset.variables['var'][:]
... your changes ...
dset.close() 
person Adrien Bax    schedule 02.01.2017

Soln 1: Python xarray

Это решение использует xarray для чтения и записи файла netcdf, а также функцию пакета где, чтобы условно сбросить значения.

import xarray as xr
ds=xr.open_dataset('test.nc')
ds['var']=xr.where((ds['var']<0),-1,ds['var'])
ds.to_netcdf('modified_test.nc') # rewrite to netcdf

Soln 2: NCO из командной строки

Я знаю, что OP хочет решение на Python, но в случае, если кто-то хочет быстро выполнить эту задачу из командной строки, есть также способ сделать это с помощью nco:

ncap2 -s 'where(x<0.) x=-1;' input.nc -O output.nc

согласно этому сообщению: значения настройки ниже порог для порога в файле netcdf

person Adrian Tompkins    schedule 09.06.2019

Чтобы включить условные вычисления с уравнением вместо вычисления только с константой, я включил условную итерацию для переменной с формой (месяц, лат, долг) на основе кода @jhamman следующим образом:

import netCDF4 as nc
import numpy as np
import time

Tmin = -1.7
Tmax = 4.9
perc = (Tmax-Tmin)/100

lats = np.arange(0,384,1)
lons = np.arange(0,768,1)
months = [0,1]
dset = nc.Dataset('path/file.nc', 'r+')

start = time.time()
dset['var'][:][dset['var'][:] < Tmin] = 100
step1 = time.time()
print('Step1 took: ' + str(step1-start))
dset['var'][:][dset['var'][:] > Tmax] = 0
step2 = time.time()
print('Step2 took: ' + str(step2 - step1))

#start iteration of each dimension to alter individual values according to equation new_value = 100-((Old_value +1.8)/1%)
for m in months:
    newstart = time.time()
    for i in lats:
        step3 = time.time()
        print('month lats lat layer '+str(i)+' took: '+str(step3-newstart) +'s')
        for j in lons:
            if dset['var'][m,i,j] < Tmax and dset['var'][m,i,j] > Tmin:
                dset['var'][m,i,j] = 100-((dset['var'][m,i,j]+1.8)/perc)       

     end = time.time()
     print('One full month took: ' + str(end-start) +'s')  

dset.close() 

Однако проблема в том, что это становится очень медленным кодом.

Step1 took: 0.0343s
Step2 took: 0.0253s
month lats lat layer: 0.4064s
One full month took 250.8082s

Это логика из-за итераций. Однако мне было интересно, есть ли у кого-нибудь из вас идея, как это немного ускорить. Действительно ли итерации необходимы для достижения этой цели?

person Linda    schedule 11.05.2020