- 积分
- 492
- 贡献
-
- 精华
- 在线时间
- 小时
- 注册时间
- 2021-12-11
- 最后登录
- 1970-1-1
|
登录后查看更多精彩内容~
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 XiaoMaFenJu 于 2023-11-7 20:10 编辑
原代码来自:
https://blog.csdn.net/mihuanchengbao/article/details/127572695
因python中没有现成的包去计算面积加权平均(即NCL中的wgt_areaave),故找到作者"可乐要加冰_ice"的代码,但计算时间过长,故在此利用numpy进行改进,代码如下:- def AreaWeightMean(data2D, lat, lon):
- '''
- data2D: 要进行区域加权平均的变量 2D: [lat, lon]
- lat: data2D对应的纬度 1D -90° 和 90° 因为NCL 和 Python 计算 np.cos(90 * rad) 值差的很大,故使用89.9°进行替代计算
- lon: data2D对应的经度 1D
- '''
- if lat.data[0] == 90:
- lat.data[0] = 89.9
- pass
- if lat.data[-1] == -90:
- lat.data[-1] = -89.9
- pass
- jlat = lat.shape[0]
- rad = 4.0 * np.arctan(1.0) / 180.0
- re = 6371220.0
- rr = re * rad
- dlon = np.abs(lon[1] - lon[0]) * rr
- dx = dlon * np.cos(lat * rad)
- dy = np.zeros(jlat)
- dy[0] = np.abs(lat[1] - lat[0]) * rr
- dy[1: jlat - 1] = np.abs(lat[2: jlat].values-lat[0: jlat - 2].values)*rr * 0.5
- dy[jlat - 1] = abs(lat[jlat - 1] - lat[jlat - 2]) * rr
- area = dx * dy
-
- weight = np.expand_dims(area, 1).repeat(len(lon), axis=1)
- new_data = np.average(data2D, weights=weight)
- return new_data
复制代码
本代码改进地方有二:一是在纬度存在90°/-90°时,因极点处权重差距不合理,选取89.9°进行替代计算;二是利用np.average()函数加快计算过程;三是源代码在dy[0]处有问题,已更改
=======================2023.11.04============================
面积加权本质就是随纬度升高、平面半径有所减小,重点就在cos(lat)上,故进行重写并忽略无关因素,且支持3维数据,代码如下:- def Area_Mean(data, lat, lon):
- '''
- by XiaoMaFenJu
- data: 要进行区域加权平均的变量,支持2、3维 2D: [lat, lon] 3D:[time, lat, lon]
- lat: data2D对应的纬度 1D
- lon: data2D对应的经度 1D
- '''
- if data.ndim == 2:
- y_weight2D = abs(np.cos(lat*np.pi/180))
- weight2D = np.expand_dims(y_weight2D, 1).repeat(len(lon), axis=1)
- # print(weight2D)
- new_data = np.average(data, weights=weight2D)
- return new_data
- elif data.ndim == 3:
- y_weight2D = abs(np.cos(lat*np.pi/180))
- weight2D = np.expand_dims(y_weight2D, 1).repeat(len(lon), axis=1)
- weight3D = np.expand_dims(weight2D,0).repeat(len(data[:,0,0]),axis=0)
- print(weight3D.shape)
- new_data = np.average(data, weights=weight3D, axis=(-1, -2))
- return new_data
- else:
- print('输入数据非2&3维')
复制代码 新函数计算所得结果与老函数几乎相同。对于全球气温数据来说90°的差异造成的影响很小,故新函数就没有对90°进行特别处理。
|
|