如何使用 python 在 NetCDF 文件中写入变量属性

How to write variable attributes in NetCDF file using python

我正在尝试将 Numpy 数组写入 netcdf 文件,该文件最终将作为具有时间维度的栅格文件读入 ArcGIS 10.2。当 ArcGIS 读取我的当前文件时,它没有正确设置 man、min 和 missing 值,因此我假设我需要在创建 NetCDF 文件时设置这些值。但是,我在创建文件时无法弄清楚如何设置这些变量属性。 这是我当前的代码。

import numpy as n
from scipy.io import netcdf

def gis_netcdf(data,arr,filename):
  f=netcdf.netcdf_file(outfile+filename,'w')
  f.history='Downscaled CMIP5 data which has been averaged over all'\
    'models and decadaly averaged'

  f.createDimension('time',9)
  f.createDimension('lat',len(data['lat']))
  f.createDimension('lon',len(data['lon']))

  time=f.createVariable('time',int,('time',))
  lat=f.createVariable('lat',float,('lat',))
  lon=f.createVariable('lon',float,('lon',))
  fog=f.createVariable('fog',float,('time','lat','lon',))

  #attributes I need set:
  #  'missing_value':1e20
  #  'valid_min':n.min(arr[arr<500])
  #  'valid_max':n.max(arr[arr<500])

  time[:]=n.arange(2010,2091,10)
  time.units='decades since 1950' 

  lat[:]=data['lat']
  lat.units='Degrees North'

  lon[:]=data['lon']
  lon.units='Degrees East'

  fog[:]=arr
  fog.units='Change in Hours'

  f.close

*****尝试发布的解决方案**********

我在上面的代码中添加了以下几行:

  fog.missing_value=1e20
  fog.valid_min=n.min(arr[arr<500])
  fog.valid_max=n.max(arr[arr<500])

它没有用。这是我的 ncdump 输出

netcdf pixel_model_fog85 {
dimensions:
        time = 9 ;
        lat = 20 ;
        lon = 18 ;

variables:
        double lat(lat) ;
                lat:units = "Degrees North" ;
        double lon(lon) ;
                lon:units = "Degrees East" ;
        double fog(time, lat, lon) ;
                fog:units = "Change in Hours" ;
        long time(time) ;
                time:units = "decades since 1950" ;

// global attributes:
                :history = "Downscaled CMIP5 data which has been        averaged over all models and decadaly averaged" ;

data:

 lat = 36.3125, 36.4375, 36.5625, 36.6875, 36.8125, 36.9375, 37.0625,
    37.1875, 37.3125, 37.4375, 37.5625, 37.6875, 37.8125, 37.9375, 38.0625,
38.1875, 38.3125, 38.4375, 38.5625, 38.6875 ;

您只需按照与 units 属性相同的方式定义它们。

fog.missing_value = 1e20
fog.valid_min = [whatever value this should be]

-- 编辑--

这是一个完整的示例脚本,在我这边运行良好。请注意,在将任何数据填充到变量之前,我在单个部分中定义了所有属性。在变量定义期间,我还使用了数据类型快捷方式,如 'i' 和 'f4'。虽然这有效,但我确实建议从 Scipy netCDF 包切换到 python-netCDF4.

import numpy as np

from scipy.io.netcdf import netcdf_file

# Define some dummy data
time_arr = range(10)
lat_arr = np.array([30.5, 40., 40.5])
lon_arr = np.array([200., 203., 206.])
ntim, nlat, nlon = len(time_arr), len(lat_arr), len(lon_arr)

fog_arr = np.random.randn(ntim,nlat,nlon)

# Write out data to a new netCDF file with some attributes
filename = netcdf_file('./tmp_netcdf.nc', 'w')

# Dimensions
filename.createDimension('time', ntim)
filename.createDimension('lat', nlat)
filename.createDimension('lon', nlon)

# Variables
time = filename.createVariable('time', 'i', ('time',))
lat = filename.createVariable('lat', 'f4', ('lat',))
lon = filename.createVariable('lon', 'f4', ('lon',))
fog = filename.createVariable('fog', 'f4', ('time', 'lat', 'lon',))

# Attributes
time.units = 'decades since 1950'
lat.units = 'degrees north'
lon.units = 'degrees east'
fog.units = 'change in hours'
fog.missing_val = 1e20
fog.valid_min = np.min(fog_arr)

# Populate the variables with data
time[:] = time_arr
lat[:] = lat_arr
lon[:] = lon_arr
fog[:,:,:] = fog_arr[:,:,:]

filename.close()

正在使用 ncdump 检查:

>>> ncdump -h tmp_netcdf.nc
netcdf tmp_netcdf {
dimensions:
time = 10 ;
lat = 3 ;
lon = 3 ;
variables:
float fog(time, lat, lon) ;
    fog:units = "change in hours" ;
    fog:valid_min = -2.33124982071635 ;
    fog:missing_val = 1.e+20f ;
int time(time) ;
    time:units = "decades since 1950" ;
float lat(lat) ;
    lat:units = "degrees north" ;
float lon(lon) ;
    lon:units = "degrees east" ;
}