社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python实现逐步订正法

happy科研 • 3 年前 • 535 次点击  
以下全文代码均已发布至和鲸社区,复制下面链接或者阅读原文前往,可一键fork跑通:

https://www.heywhale.com/mw/project/61bc71dc7e520c001798e15a?shareby=6194fef0f4be9e0017857668


一 背景介绍
早的客观分析是利用多项式插值将观测资料插值到模式的规则网格,但是观测资料较为稀疏,没有充足的资料用做模式的初始化,利用空间插值将观测插到规则网格点上是不够的。

在资料丰富地区,来源于观测资料的信息占主导地位;而在资料稀少的地区预报会得益于先验的信息(背景场,第一猜测场),最早的先验信息是使用气候态的场,目前一般使用短期预报的结果做为格点的第一猜值。引入第一猜值的第一种方法SCM,是瑞典科学家BergthorssonDoos(1955)以及美国NWSCressman(1959)所发展的,引入背景场是资料同化历史上的一次重大思维突破,。
 
二 SCM理论分析介绍
①首先确定影响半径 ,影响半径范围内包含Ki个观测,为观测值。即在某点,它的值由该半径内的观测共同影响。
 


②网格点的初始估计是由背景场给出,第一次估计以后,在由逐步订正引入观测:
 
假定2=0,表明极度相信观测值;20,则假定观测本身是有误差的,同时给与背景场相应的权重。该公式表示,某点的值Ti由该点的背景场值+(系数1*观测增量1+系数1*观测增量1+...)/系数和。其中系数,Cressman(1959)定义的系数如下:

其中,R表示影响半径;r表示测站与格点i的距离。表明观测资料对格点的订正只考虑距离该格点半径R内的那些测站。
 
三 实例及代码实现
实例描述:如下图所示,白色部分表示陆地,彩色部分表示海洋已有的初猜值。现有两个观测点obs0obs1的观测资料,利用逐步订正法将观测资料同化进去。

运行后,发现观测资料已经被同化进背景场,对于观测站obs0,在影响半径内,都对背景场进行了调整,而两个观测站影响相交部分则由两个站共同决定。同样我们也发现了逐步订正法的优缺点,优点在于第一次引入了背景场和引入了观测增量,相对比较简单。缺点在于权重函数是经验给定的,给“密集区”观测和相对独立观测同样的权重是不合理。同样,对于观测较少的区域,例如obs0单独影响的区域,在边界地区也不够平滑。

 
代码如下:
import scipy.ioimport pandas as pdimport numpy as npimport matplotlib.pyplot as plt R=0.5#影响半径 def findsite(x,y,latSite,lonSite): #x,经度矩阵,y,纬度矩阵;从x,y中找出距离(latSite,lonSite)最近的点id. dis=np.sqrt(np.square(x-lonSite)+np.square(y-latSite)) mindis_index=np.argmin(dis) lon_site=x[mindis_index]; lat_site=y[mindis_index]; seri_index=np.where(x==lon_site)[0] return seri_index#加载数据,背景场和观测资料back_file =scipy.io.loadmat(r'back_ground.mat')back_ground= back_file['back_ground']obs_file =scipy.io.loadmat(r'obs.mat')obs =obs_file['obs'] back_ground=pd.DataFrame(back_ground)back_ground.columns=['lon','lat','surge']obs=pd.DataFrame(obs)obs.columns=['lon','lat','obs'] #计算格点与观测点的距离dis0=np.sqrt(np.square(back_ground['lon']-obs['lon'][0])+np.square(back_ground['lat']-obs['lat'][0]))dis1=np.sqrt(np.square(back_ground['lon']-obs['lon'][1])+np.square(back_ground['lat']-obs['lat'][1]))back_ground['dis0']=dis0back_ground['dis1']=dis1 #计算Creseeman系数w0=(R**2-dis0**2)/(R**2+dis0**2)w1=(R**2-dis1**2)/(R**2+dis1**2) #小于0即超出了影响半径w0[w0<0]=0w1[w1<0]=0 #找出离观测点最近的背景场值obs_index0=findsite(back_ground['lon'],back_ground['lat'],obs['lat'][0],obs['lon'][0])obs_index1=findsite(back_ground['lon'],back_ground['lat'],obs['lat'][1],obs['lon'][1])background_obs0=back_ground.iloc[obs_index0]['surge'].valuesbackground_obs1=back_ground.iloc[obs_index1]['surge'].values #观测增量back_ground['bluking0']=float(obs['obs'][0]-background_obs0)back_ground['bluking1']=float(obs['obs'][1]-background_obs1)back_ground['w0']=w0back_ground['w1']=w1back_ground['surge1']=back_ground['surge'] #遍历每个点,计算插值后的值for i in range(0, len(back_ground)): if (back_ground.iloc[i]['w0']!=0) |(back_ground.iloc[i]['w1']!=0) : #if back_ground[(back_ground['w0']!=0)|(back_ground['w1']!=0)]: #print('1') back_ground.loc[i,'surge1']=back_ground.iloc[i]['surge']+(((back_ground.iloc[i]['w0']*back_ground.iloc[i]['bluking0']+ back_ground.iloc[i]['w1']*back_ground.iloc[i]['bluking1']))/(back_ground.iloc[i]['w0']+back_ground.iloc[i]['w1']))#画图检验 plt.figure(0)plt.scatter(back_ground['lon'].values,back_ground['lat'].values,20,back_ground['surge'].values)plt.colorbar()plt.title('Assimilationbefore')plt.scatter(obs['lon'][0],obs['lat'][0],20)plt.text(obs['lon'][0],obs['lat'][0], 'obs0', fontdict={'size' :14, 'color': 'red'})plt.scatter(obs['lon'][1],obs['lat'][1],20)plt.text(obs['lon'][1],obs['lat'][1], 'obs1', fontdict={'size':14, 'color': 'red'})plt.show()#plt.savefig('before.png') plt.figure(1)plt.scatter(back_ground['lon'].values,back_ground['lat'].values,20,back_ground['surge1'].values)plt.colorbar()plt.title('Afterassimilation')plt.scatter(obs['lon'][0],obs['lat'][0],20,'r')plt.text(obs['lon'][0],obs['lat'][0], 'obs0', fontdict={'size':14, 'color': 'red'})plt.scatter(obs['lon'][1],obs['lat'][1],20)plt.text(obs['lon'][1],obs['lat'][1], 'obs1', fontdict={'size':14, 'color': 'red'})plt.show()#plt.savefig('after.png')
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/125030
 
535 次点击