【问题标题】:Python : Replacing Values in netcdf file using netCDF4Python:使用 netCDF4 替换 netcdf 文件中的值
【发布时间】:2015-10-30 04:06:39
【问题描述】:

我有一个 netcdf 文件,其中有几个值

import netCDF4

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

【问题讨论】:

    标签: python netcdf python-xarray nco


    【解决方案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
    

    【讨论】:

    • 如果使用 scale_factor 和 add_offset 压缩变量,请小心。在这种情况下,只有由 fill_value 属性指定的值才会被直接写入文件。任何其他值都将被自动压缩。
    【解决方案2】:

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

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

    【讨论】:

    • ... your changes ... 可以使用一些详细说明。恕我直言,这个答案相当不完整,也不是很有用。
    【解决方案3】:

    解决方案 1:Python xarray

    本方案使用xarray读写netcdf文件,包的函数where有条件地重置值。

    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
    

    根据这篇文章:setting values below a threshold to the threshold in a netcdf file

    【讨论】:

    • 这是一个不错的解决方案!是否有涉及不会重写文件的 xarray 解决方案?而只是更新更改的值?
    【解决方案4】:

    为了使用方程式而不是仅使用常数进行条件计算,我根据@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
    

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

    【讨论】:

      猜你喜欢
      • 2016-11-08
      • 2016-04-27
      • 2016-03-25
      • 2021-03-23
      • 2015-12-14
      • 2018-07-08
      • 2013-08-10
      • 1970-01-01
      • 2020-06-12
      相关资源
      最近更新 更多