WRF netcdf文件 - 基于python

时间:2016-02-09 16:59:02

标签: python arrays numpy netcdf weather

我有两个来自WRF运行的netcdf文件,一个包含每小时数据,另一个较小的文件包含坐标(XLAT和XLONG)。我试图根据某些坐标检索数据的子集。

其中一个变量的例子是温度' T2'其尺寸(1,1015,1359)分别为(time,south_north,west_east)。

XLAT和XLONG具有相同的尺寸(1,1015,1359)。

有一个相同的问题(请参阅netcdf4 extract for subset of lat lon),因为我的纬度/长度尺寸有点不同,脚本对我不起作用,我还没有找到原因。我试图将坐标更改为1D数组,因此它与上一个问题类似,但脚本不起作用,我得到索引错误。

如果有人能帮助我,那会很棒!在此先感谢:)

import numpy as np
from netCDF4 import Dataset  
import matplotlib.pyplot as plt

lons = b.variables['XLONG'][:]
lats = b.variables['XLAT'][:]

lons2d =lons.reshape((1015,1359))
lons1d = lons2d.reshape((1379385))

lats2d =lats.reshape((1015,1359))
lats1d = lats2d.reshape((1379385))

lat_bnds, lon_bnds = [49,53], [-125,-115]
lat_inds = np.where((lats1d > lat_bnds[0]) & (lats1d < lat_bnds[1]))
lon_inds = np.where((lons1d > lon_bnds[0]) & (lons1d < lon_bnds[1]))

T_subset = a.variables['T2'][:,lat_inds,lon_inds]

但是我收到以下错误:

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-2-0f8890d3b1c5> in <module>()
 25 lon_inds = np.where((lons1d > lon_bnds[0]) & (lons1d < lon_bnds[1]))
 26 
---> 27 T_subset = a.variables['T2'][:,lat_inds,lon_inds]
 28 
 29 

netCDF4/_netCDF4.pyx in      netCDF4._netCDF4.Variable.__getitem__(netCDF4/_netCDF4.c:35672)()

/Users/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/netCDF4/utils.pyc in _StartCountStride(elem, shape, dimensions, grp, datashape, put)
197         # Raise error if multidimensional indexing is used.
198         if ea.ndim > 1:
--> 199             raise IndexError("Index cannot be multidimensional")
200         # set unlim to True if dimension is unlimited and put==True
201         # (called from __setitem__)
IndexError: Index cannot be multidimensional

2 个答案:

答案 0 :(得分:1)

我不确定为什么它不能正常工作,但我认为这可以做你想要的并且更清洁:

import numpy as np
from netCDF4 import Dataset
import matplotlib.pyplot as plt

# By indexing at 0 along first dimension, we eliminate the time
# dimension, which only had size 0 anyway.
lons = b.variables['XLONG'][0]
lats = b.variables['XLAT'][0]
temp = a.variables['T2'][0]

lat_bnds, lon_bnds = [49,53], [-125,-115]

# Just AND together all of them and make a big mask
subset = ((lats > lat_bnds[0]) & (lats < lat_bnds[1]) & 
          (lons > lon_bnds[0]) & (lons < lon_bnds[1]))

# Apply mask--should apply to trailing dimensions...I think
T_subset = temp[subset]

答案 1 :(得分:0)

我发现lat_inds存在明显问题,因为它具有最大形状1015*1359,但您尝试将其用作纬度索引,其大小为1015。因此IMO您应首先找到lat_indslon_inds的类似值,这些值满足lon和lat限制,然后将此数组用于展平数据。类似的东西:

uni_ind=numpy.intersect1d(lat_inds,lon_inds)
T_subset=np.ravel(a.variables['T2'])[uni_ind]

将数组转换回2D可能包含更多问题,因为我假设您的原始数据不在圆柱坐标中,因此结果子集可能不是矩形。 此代码未经过测试,如果您共享原始数据文件,我也可以这样做。

编辑: 为了正确绘图,使用掩蔽更容易,这个例子应该足够信息。

import numpy as np
from netCDF4 import Dataset
import matplotlib.pyplot as plt

b = Dataset('wrfout_conus_constants.nc')
a = Dataset('wrf2d_d01_2010-01-11_000000')

## Data coords
xlong = b.variables['XLONG'][0]
xlat = b.variables['XLAT'][0]
## Data var
temp = a.variables['T2'][0]
## Data bounds
longmax, longmin = -115, -125
latmax, latmin = 53, 49
## Mask coordinates according to bounds
latmask=np.ma.masked_where(xlat<latmin,xlat).mask+np.ma.masked_where(xlat>latmax,xlat).mask
lonmask=np.ma.masked_where(xlong<longmin,xlong).mask+np.ma.masked_where(xlong>longmax,xlat).mask
totmask = lonmask + latmask
## Show mask compared to full domain
plt.pcolormesh(totmask)
## Apply mask to data
temp_masked = np.ma.masked_where(totmask,temp)
## plot masked data
fig=plt.figure()
plt.contourf(temp_masked)
## plot full domain
fig=plt.figure()
plt.contourf(temp)
plt.show()