笔记 | nco | 如何修改NC文件变量的数值及单位
公众号:气python风雨
Image Name关注我获取更多学习资料,第一时间收到我的Python学习资料,也可获取我的联系方式沟通合作
前言
读者提供了一个nc数据,说想要修改nc数据中深度的单位与数值
问有无方便的方法
由于读者无python基础,那么我基于nco做了以下教程
nco(NetCDF Operator)是一组用于处理和分析NetCDF文件的命令行工具。诸多前辈称其为最强的nc软件
那么我们试试是否好用吧
计算过程
确认变量的名称和单位
首先我们将查看一下数据描述
!ncdump -h /home/mw/project/thetao_Omon_HadGEM2-ES_rcp85_r1i1p1_229912-229912.nc
输出:
netcdf thetao_Omon_HadGEM2-ES_rcp85_r1i1p1_229912-229912 {dimensions: time = UNLIMITED ; // (1 currently) lev = 40 ; lat = 216 ; lon = 360 ; bnds = 2 ;variables: double time(time) ; time:bounds = "time_bnds" ; time:units = "days since 1859-12-01" ; time:calendar = "360_day" ; time:axis = "T" ; time:long_name = "time" ; time:standard_name = "time" ; double time_bnds(time, bnds) ; double lev(lev) ; lev:bounds = "lev_bnds" ; lev:units = "m" ; lev:axis = "Z" ; lev:positive = "down" ; lev:long_name = "ocean depth coordinate" ; lev:standard_name = "depth" ;...}
那么我们可以看到高度的变量叫做lev,下面对lev进行操作,查看进一步的信息
!ncdump -v lev /home/mw/project/thetao_Omon_HadGEM2-ES_rcp85_r1i1p1_229912-229912.nc
输出:
...data: lev = 5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105, 115, 125, 135.600006103516, 148.5, 165.949996948242, 190.25, 223.600006103516, 268.100006103516, 325.799987792969, 398.600006103516, 488.25, 596.400024414062, 724.5, 873.849975585938, 1045.59997558594, 1240.69995117188, 1459.90002441406, 1703.69995117188, 1972.40002441406, 2265.80004882812, 2581.75, 2914.94995117188, 3257.5, 3602.5, 3947.5, 4292.5, 4637.5, 4982.5, 5327.5 ;}
修改数值
我们还获得了其单位和具体数值,下面进行数值操作
例如我们需要将m转为cm,那么数值上x100
下面是一个示例命令,它会读取原始文件nc,然后将lev变量的值乘100,并将结果写入新的文件test.nc中
!ncap2 -s 'lev=lev*100.0' /home/mw/project/thetao_Omon_HadGEM2-ES_rcp85_r1i1p1_229912-229912.nc test.nc
!ncdump -v lev /home/mw/project/test.nc
输出:
...data: lev = 500, 1500, 2500, 3500, 4500, 5500, 6500, 7500, 8500, 9500, 10500, 11500, 12500, 13560.0006103516, 14850, 16594.9996948242, 19025, 22360.0006103516, 26810.0006103516, 32579.9987792969, 39860.0006103516, 48825, 59640.0024414062, 72450, 87384.9975585938, 104559.997558594, 124069.995117188, 145990.002441406, 170369.995117188, 197240.002441406, 226580.004882812, 258175, 291494.995117188, 325750, 360250, 394750, 429250, 463750, 498250, 532750 ;}
修改单位
成功将lev的数值乘100了,下面修改其单位
!ncatted -a units,lev,o,c,"cm" test.nc
!ncdump -v lev test.nc
输出:
... double lev(lev) ; lev:axis = "Z" ; lev:bounds = "lev_bnds" ; lev:long_name = "ocean depth coordinate" ; lev:positive = "down" ; lev:standard_name = "depth" ; lev:units = "cm" ;...
修改完成
如何补充数据
如果你有一组具体的数值要用来添加到lev变量,你可以创建一个临时的NetCDF文件,将这些数值写入一个名为lev的变量
python新建临时nc数据
import numpy as npfrom netCDF4 import Dataset# 创建一个新的NetCDF文件file_path = 'temp_lev.nc'nc = Dataset(file_path, 'w', format='NETCDF4')# 定义维度dim_name = 'level'dim_size = 5# 假设你有5个层次的数据nc.createDimension(dim_name, dim_size)# 创建变量var_name = 'lev'lev_var = nc.createVariable(var_name, 'f4', (dim_name,))# 给变量添加单位属性(可选)lev_var.units = 'm'# 或者其他的单位# 写入数据# 这里我们假设有一些数据,例如从0到4data = np.array([0.0, 1.0, 2.0, 3.0, 4.0])lev_var[:] = data# 关闭文件nc.close()print(f"Temporary NetCDF file '{file_path}' created with variable 'lev'.")
!ncks -A -v lev temp_lev.nc test.nc
输出:
ncks: WARNING nco_cpy_var_dfn_trv() reports variable "lev" output type = NC_DOUBLE does not equal input type = NC_FLOAT...
!ncdump -v lev test.nc
输出:
...data: lev = 0, 1, 2, 3, 4, 5500, 6500, 7500, 8500, 9500, 10500, 11500, 12500, 13560.0006103516, 14850, 16594.9996948242, 19025, 22360.0006103516, 26810.0006103516, 32579.9987792969, 39860.0006103516, 48825, 59640.0024414062, 72450, 87384.9975585938, 104559.997558594, 124069.995117188, 145990.002441406, 170369.995117188, 197240.002441406, 226580.004882812, 258175, 291494.995117188, 325750, 360250, 394750, 429250, 463750, 498250, 532750 ;}
可以看到设置的五层深度已经添加到数据中了,注意格式什么都需要一致才才行
修改时间属性与数值
!ncdump -v time test.nc
输出:
...data: time = 158415 ;}
修改时间属性:
!ncap2 -s 'time@units="days since days since 1859-12-01"; time@calendar="gregorian";' test.nc newfile.nc!ncdump -v time newfile.nc
输出:
double time(time) ; time:bounds = "time_bnds" ; time:units = "days since days since 1859-12-01" ; time:calendar = "gregorian" ;...
修改时间数值:
!ncap2 -s 'time=time+10' test.nc newfile2.nc!ncdump -v time newfile2.nc
输出:
...data: time = 158425 ;}