读者提供了一个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的变量
import numpy as np
from 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到4
data = 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 ;
}