- 积分
- 22715
- 贡献
-
- 精华
- 在线时间
- 小时
- 注册时间
- 2011-7-23
- 最后登录
- 1970-1-1
|
登录后查看更多精彩内容~
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 平流层的萝卜 于 2020-10-15 10:40 编辑
气象中应该会经常遇到算一个区域内的平均值问题。有时候区域是矩形,则grads的aave可以直接解决;有时候区域是不规则的,比如说河南省地区。如果用格点资料算河南省的平均降水量,就涉及到不规则区域的面积平均问题。
本帖记录一下使用Python解决任意polygon(任意区域)的简单面积平均问题。
PS:所谓简单面积平均,即不涉及面积内的经纬度和权重等复杂运算,仅仅是面积内的格点的值的平均。
具体分为以下几步:
1)确定要算平均的区域,将该区域的point所围成的polygon多边形转换为matplotlib中的path。可以从shp文件中获取感兴趣的区域,比如西藏自治区(注意藏南和阿克赛钦部分),北京大兴县,江浙沪三地总辖区等。这里用shp文件提取感兴趣区时,使用的代码片段出自我以前的python maskout帖子:http://bbs.06climate.com/forum.php?mod=viewthread&tid=42437
2)判断有哪些点落在这个path里。此处利用Path里的contains_point方法,得到一个在或不在区域内的bool型array。
3)利用上一步的array,将区域外的降水量(或者其他变量)的值转化为np.nan。结合np.nanmean方法可以排除np.nan值,从而直接计算降水量(或者其他变量)的简单面积均值。
由于手头的降水数据较大,所以给一个计算海拔高度的面积平均的例子,代码和示例文件如下:- #coding=utf-8
- import numpy as np
- import shapefile
- import netCDF4 as nc
- from matplotlib.path import Path
- from mpl_toolkits.basemap import Basemap
- import matplotlib.pyplot as plt
- ncfile=nc.Dataset(r'surface_z_0.25_46_36_115_128.nc')
- lons=ncfile.variables['longitude'][:]
- lats=ncfile.variables['latitude'][:]
- z=ncfile.variables['z'][0,:,:]
- xx,yy=np.meshgrid(lons,lats)
- x,y=xx.flatten(),yy.flatten()
- points=np.vstack((x,y)).T
- # print yy
- # exit()
- sf=shapefile.Reader(r'bou2_4p',' ')
- vertices = []
- codes = []
- for shape_rec in sf.shapeRecords():
- # print record
- if shape_rec.record[4] in [210000,110000,120000]: ###辽宁、北京和天津的行政编码,百度可查
- pts = shape_rec.shape.points
- prt = list(shape_rec.shape.parts) + [len(pts)]
- for i in range(len(prt) - 1):
- for j in range(prt[i], prt[i+1]):
- vertices.append((pts[j][0], pts[j][1]))
- codes += [Path.MOVETO]
- codes += [Path.LINETO] * (prt[i+1] - prt[i] -2)
- codes += [Path.CLOSEPOLY]
- clip = Path(vertices, codes)
- polygon_of_Liaoning_beijing_tianjin= clip
- # exit()
- bool_grid_1d = polygon_of_Liaoning_beijing_tianjin.contains_points(points)
- bool_grid_original_shape=bool_grid_1d.reshape(xx.shape)
- ###########################################################################
- ###### Highlighting grids within the area using scatterplot################
- ###########################################################################
- m = Basemap(llcrnrlat=lats[-1], llcrnrlon=lons[0], urcrnrlat=lats[0], urcrnrlon=lons[-1])
- m.readshapefile(r'E:\shpmap\bou2_4p', ' ', color='grey', linewidth=2)
- m.drawparallels(np.linspace(lats[0],lats[-1],10), labels=[1, 0, 0, 0], linewidth=0.5, fontsize=20)
- m.drawmeridians(np.linspace(lons[0],lons[-1],10), labels=[0, 0, 0, 1], linewidth=0.5, fontsize=20)
- x[~bool_grid_1d]=np.nan
- y[~bool_grid_1d]=np.nan
- m.scatter(x,y,s=10,color='red')
- ###########################################################################
- ###### Calculating area mean by np,nanmean#################################
- ###########################################################################
- z[~bool_grid_original_shape]=np.nan
- print np.nanmean(z)/9.8
- plt.show()
复制代码
点的位置的示意图如下:
最后得到的计算结果如下:
可见,北京市、天津市和辽宁省三地的平均地形海拔高度为236m。
脚本、海拔高度数据和地图边界文件打包上传了,可下载使用:
area_mean.rar
(626.66 KB, 下载次数: 66)
|
评分
-
查看全部评分
|