繁体   English   中英

Python:使用 netCDF4 替换 netcdf 文件中的值

[英]Python : Replacing Values in netcdf file using netCDF4

我有一个 netcdf 文件,其中有几个值 < 0。我想用一个值(比如 -1)替换所有这些值。 我如何使用 netCDF4 做到这一点? 我正在阅读这样的文件:

import netCDF4

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

如果要将数据保留在 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

对我来说,以前的答案不起作用,我用以下方法解决了它:

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

解决方法 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

解决方法 2:来自命令行的 NCO

我知道 OP 需要一个 python 解决方案,但如果有人只想从命令行快速执行此任务,还有一种方法可以使用 nco:

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

根据这篇文章: 将低于阈值的值设置为 netcdf 文件中的阈值

为了使用方程启用条件计算,而不是仅使用常量进行计算,我根据@jhamman 的代码对形状为 (month,lats,lons) 的变量进行了条件迭代,如下所示:

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

这是由于迭代的逻辑。 但是,我想知道你们中是否有人知道如何加快速度。 这个目标真的需要迭代吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM