爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 1483|回复: 12

[经验总结] Python实现纬度加权平均

[复制链接]

新浪微博达人勋

发表于 2023-9-21 17:19:02 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 XiaoMaFenJu 于 2023-11-7 20:10 编辑

原代码来自:
https://blog.csdn.net/mihuanchengbao/article/details/127572695

因python中没有现成的包去计算面积加权平均(即NCL中的wgt_areaave),故找到作者"可乐要加冰_ice"的代码,但计算时间过长,故在此利用numpy进行改进,代码如下:
  1. def AreaWeightMean(data2D, lat, lon):
  2.     '''
  3.     data2D: 要进行区域加权平均的变量  2D: [lat, lon]
  4.     lat: data2D对应的纬度 1D -90° 和 90°  因为NCL 和 Python 计算 np.cos(90 * rad) 值差的很大,故使用89.9°进行替代计算
  5.     lon: data2D对应的经度 1D
  6.     '''
  7.     if lat.data[0] == 90:
  8.         lat.data[0] = 89.9
  9.         pass
  10.     if lat.data[-1] == -90:
  11.         lat.data[-1] = -89.9
  12.         pass

  13.     jlat = lat.shape[0]
  14.     rad = 4.0 * np.arctan(1.0) / 180.0
  15.     re = 6371220.0
  16.     rr = re * rad
  17.     dlon = np.abs(lon[1] - lon[0]) * rr
  18.     dx = dlon * np.cos(lat * rad)
  19.     dy = np.zeros(jlat)
  20.     dy[0] = np.abs(lat[1] - lat[0]) * rr
  21.     dy[1: jlat - 1] = np.abs(lat[2: jlat].values-lat[0: jlat - 2].values)*rr * 0.5
  22.     dy[jlat - 1] = abs(lat[jlat - 1] - lat[jlat - 2]) * rr
  23.     area = dx * dy
  24.    
  25.     weight = np.expand_dims(area, 1).repeat(len(lon), axis=1)
  26.     new_data = np.average(data2D, weights=weight)
  27.     return new_data
复制代码


本代码改进地方有二:一是在纬度存在90°/-90°时,因极点处权重差距不合理,选取89.9°进行替代计算;二是利用np.average()函数加快计算过程;三是源代码在dy[0]处有问题,已更改


=======================2023.11.04============================
面积加权本质就是随纬度升高、平面半径有所减小,重点就在cos(lat)上,故进行重写并忽略无关因素,且支持3维数据,代码如下:
  1. def Area_Mean(data, lat, lon):
  2.     '''
  3.     by XiaoMaFenJu
  4.     data: 要进行区域加权平均的变量,支持2、3维  2D: [lat, lon]  3D:[time, lat, lon]
  5.     lat: data2D对应的纬度 1D
  6.     lon: data2D对应的经度 1D
  7.     '''

  8.     if data.ndim == 2:
  9.         y_weight2D = abs(np.cos(lat*np.pi/180))
  10.         weight2D = np.expand_dims(y_weight2D, 1).repeat(len(lon), axis=1)
  11.         # print(weight2D)
  12.         new_data = np.average(data, weights=weight2D)
  13.         return new_data
  14.     elif data.ndim == 3:
  15.         y_weight2D = abs(np.cos(lat*np.pi/180))
  16.         weight2D = np.expand_dims(y_weight2D, 1).repeat(len(lon), axis=1)
  17.         weight3D = np.expand_dims(weight2D,0).repeat(len(data[:,0,0]),axis=0)
  18.         print(weight3D.shape)
  19.         new_data = np.average(data, weights=weight3D, axis=(-1, -2))
  20.         return new_data
  21.     else:
  22.         print('输入数据非2&3维')
复制代码
新函数计算所得结果与老函数几乎相同。对于全球气温数据来说90°的差异造成的影响很小,故新函数就没有对90°进行特别处理。



密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2023-11-12 22:28:16 | 显示全部楼层
krwlng 发表于 2023-11-11 09:48
想问一下楼主如果数据有缺测的化需要怎么预处理呢?

可以在循环里加:mask = ~np.isnan(data)      ; data_mean = np.average(data[mask], weights=wgts[mask])  大概这样
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2023-11-4 15:05:05 | 显示全部楼层
顶一下
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

新浪微博达人勋

发表于 2023-11-11 09:48:48 | 显示全部楼层
想问一下楼主如果数据有缺测的化需要怎么预处理呢?
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2023-11-11 12:45:57 | 显示全部楼层
krwlng 发表于 2023-11-11 09:48
想问一下楼主如果数据有缺测的化需要怎么预处理呢?

我暂时没有这个需求呢,我觉得应该就是np.average跟nan的问题,你可以参考https://www.coder.work/article/371500
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2023-11-12 19:33:57 | 显示全部楼层
XiaoMaFenJu 发表于 2023-11-11 12:45
我暂时没有这个需求呢,我觉得应该就是np.average跟nan的问题,你可以参考https://www.coder.work/articl ...

感谢回复!
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2023-11-14 16:41:33 | 显示全部楼层
sunyuqing 发表于 2023-11-12 22:28
可以在循环里加:mask = ~np.isnan(data)      ; data_mean = np.average(data[mask], weights=wgts[mask ...

感谢帮助!我加了这句画出我想要的图了,非常感谢!
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2024-1-11 10:13:34 | 显示全部楼层
学习了!收藏验证一下
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 6 天前 | 显示全部楼层
我看到有的在做纬度加权时候对纬度cos进行了开方作为每个纬度的权重,请问这个开不开方有什么影响嘛
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 6 天前 | 显示全部楼层
hhhz 发表于 2024-4-22 11:09
我看到有的在做纬度加权时候对纬度cos进行了开方作为每个纬度的权重,请问这个开不开方有什么影响嘛

开方肯定是有影响的,但是我也不知道为什么会开方(我也见过有开方的)
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表