将气候学结果保存到netcdf文件

时间:2015-02-11 19:11:22

标签: python io netcdf

我想保存一个气候文件,这样每次我需要计算异常时,我都不必再运行气候学脚本(而且需要花费很多时间!)。 这些文件显然是以这种方式“CODEYYYYMMTTTT”:

hgap1981040000.nc
hgap1981040600.nc
hgap1981041200.nc
hgap1981041800.nc

我尝试使用下面的脚本将气候平均值(从netcdf计算)保存到netcdf文件中,但我收到了错误。

from pylab import *
import netCDF4 as nc
import numpy as np

u_2a=[]
v_2a=[]
w_2a=[]
u_2m=[]
v_2m=[]
w_2m=[]

#function to calculate mean values (this case, Apr-May only)    
def mon(mo):
    for yr in range (1981,1984,1):
        dir_erai = '~/era-in/netc/monthly_means/{}/hgap{}{}????.nc'.format(yr,yr,mo)
        print yr
        f = nc.MFDataset(dir_erai)
        uwnd = f.variables['U']
        vwnd = f.variables['V']
        wwnd = f.variables['W']
        u_2 = np.mean(uwnd[0:4,:,:,:],axis=0)
        v_2 = np.mean(vwnd[0:4,:,:,:],axis=0) 
        w_2 = np.mean(vwnd[0:4,:,:,:],axis=0)
        f.close()   
        u_2a.append(u_2)
        v_2a.append(v_2)
        w_2a.append(w_2)
    u_2m=np.mean(u_2a,axis=0)
    v_2m=np.mean(v_2a,axis=0)
    w_2m=np.mean(w_2a,axis=0)

    return u_2m,v_2m,w_2m


uapr,vapr,wapr = mon('04')
umay,vmay,wmay = mon('05')

uAM = np.mean([uapr,umay],axis=0)
vAM = np.mean([vapr,vmay],axis=0)
wAM = np.mean([wapr,wmay],axis=0)

root_grp = Dataset('climatology_test.nc', 'w', format='NETCDF4')
root_grp.description = 'Example climatology winds UVW'
# dimensions
root_grp.createDimension('time', None)
root_grp.createDimension('lev', 37)
root_grp.createDimension('lat', 256)
root_grp.createDimension('lon', 512)
# variables
times = root_grp.createVariable('time', 'f8', ('time',))
levels = root_grp.createVariable('level', 'f4', ('lev',))
latitudes = root_grp.createVariable('latitude', 'f4', ('lat',))
longitudes = root_grp.createVariable('longitude', 'f4', ('lon',))
U1 = root_grp.createVariable('U1', 'f4', ('time', 'lev', 'lat', 'lon',))
V1 = root_grp.createVariable('V1', 'f4', ('time', 'lev', 'lat', 'lon',))
W1 = root_grp.createVariable('W1', 'f4', ('time', 'lev', 'lat', 'lon',))

# data
levs = [1000.,975.,950.,925.,900.,875.,850.,825.,800.,775.,750.,700.,650.,600.,550.,500.,450.,400.,350.,300.,250.,200.,175.,150.,125.,100.,70.,50.,30.,20.,10.,7.,5.,3.,2.,1.,0] 
lats =  np.arange(-89.5, 89.5, 0.70)
lons =  np.arange(0., 358.4, 0.70)
levels[:] = levs
latitudes[:] = lats
longitudes[:] = lons
uAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))
vAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))
wAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))

root_grp.close()

和错误:

Traceback (most recent call last):
  File "era_uv_climatology.py", line 99, in <module>
    uAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))
IndexError: too many indices

我确实改变了

uAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))
vAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))
wAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))

U1 = uAM
V1 = vAM
W1 = wAM

我得到一个错误且空的netCDF文件,所有风值等于零,错误的lon-lat范围(1,2,3,...,256)和(1,2,3 ... 。,512)。

平均方法或赋值是错误的吗?或两者兼而有之?

3 个答案:

答案 0 :(得分:2)

第一段代码,


    uAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))
    vAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))
    wAM[:,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))

给出了这个错误,因为随机统一的形状与netcdf变量不一样。请改为尝试。


    uAM[0,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))
    vAM[0,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))
    wAM[0,:,:,:] = np.random.uniform(size=(len(levs), len(lats), len(lons)))

你最后用close方法关闭了气候学文件吗?

答案 1 :(得分:2)

除了缺少close()调用之外,您还没有将值写入变量。为此:

U1[:] = uAM
V1[:] = vAM
W1[:] = wAM

在Python中将一个变量设置为另一个变量时,如:

U1 = uAM

您只是更改U1引用的名称(点数) - 您实际上并没有更改U1指向的 对象的任何内容。因此,对于您的脚本,您重置U1以指向数据数组,并且您将丢失对您创建的NetCDF变量的引用。

答案 2 :(得分:1)

经过一些建议并重新开始编码后,我设法通过下面的脚本获得了预期的结果。但是,如何将 lon lat 值分别粘贴到 0到360 90到-90 ,仍然是一个谜。

import netCDF4 as nc
from netCDF4 import *
import numpy as np
import time
from numpy.random import uniform

u_2a=[]
v_2a=[]
w_2a=[]
u_2m=[]
v_2m=[]
w_2m=[]

def mon(mo):
    for yr in range (1981,2011,1):
        dir_erai = '~/netc/monthly_means/{}/hgap{}{}????.nc'.format(yr,yr,mo)
        print yr
        f = nc.MFDataset(dir_erai)
        uwnd = f.variables['U']
        vwnd = f.variables['V']
        wwnd = f.variables['W']
        u_2 = np.mean(uwnd[0:4,:,:,:],axis=0)
        v_2 = np.mean(vwnd[0:4,:,:,:],axis=0) 
        w_2 = np.mean(vwnd[0:4,:,:,:],axis=0)
        f.close()   
        u_2a.append(u_2)
        v_2a.append(v_2)
        w_2a.append(w_2)
    u_2m=np.mean(u_2a,axis=0)
    v_2m=np.mean(v_2a,axis=0)
    w_2m=np.mean(w_2a,axis=0)

    return u_2m,v_2m,w_2m


uapr,vapr,wapr = mon('04')
umay,vmay,wmay = mon('05')
usep,vsep,wsep = mon('09')
uoct,voct,woct = mon('10')

#creating netcdf
rootgrp = Dataset('climatology_u.nc', 'w', format='NETCDF4')
print rootgrp.data_model

level = rootgrp.createDimension('level',None)
lat = rootgrp.createDimension('lat', 256)
lon = rootgrp.createDimension('lon', 512)
print rootgrp.dimensions

levels = rootgrp.createVariable('level','i4',('level',))
latitudes = rootgrp.createVariable('latitude','f4',('lat',))
longitudes = rootgrp.createVariable('longitude','f4',('lon',))
U1 = rootgrp.createVariable('U1','f4',('level','lat','lon',))
V1 = rootgrp.createVariable('V1','f4',('level','lat','lon',))
W1 = rootgrp.createVariable('W1','f4',('level','lat','lon',))


rootgrp.description = 'Create UVW climatology'
rootgrp.source = 'netCDF4 python module tutorial'
latitudes.units = 'degrees north'
longitudes.units = 'degrees east'
levels.units = 'hPa'
U1.units = 'm/s'
V1.units = 'm/s'
W1.units = 'm/s'

lats =  np.arange(-89.5, 89.5, 0.70)
lons =  np.arange(0., 358.4, 0.70)
latitudes[:]=lats[::-1] #this probably doesn't matter
longitudes[:]=lons


nlats = len(rootgrp.dimensions['lat'])
nlons = len(rootgrp.dimensions['lon'])
print 'U1 shape before adding data = ',U1.shape
U1[0:37,:,:] = uniform(size=(37,nlats,nlons))
V1[0:37,:,:] = uniform(size=(37,nlats,nlons))
W1[0:37,:,:] = uniform(size=(37,nlats,nlons))
print 'U1 shape after adding data = ',U1.shape
levels[:] = [1000.,975.,950.,925.,900.,875.,850.,825.,800.,775.,750.,700.,650.,600.,550.,500.,450.,400.,350.,300.,250.,200.,175.,150.,125.,100.,70.,50.,30.,20.,10.,7.,5.,3.,2.,1.,0] 

U1[:,:,:]=uapr[:,::-1,:] # without "::-1", the data is upside down,sth to do with source dataset
V1[:,:,:]=vapr[:,::-1,:]
W1[:,:,:]=wapr[:,::-1,:]


rootgrp.close()