meteva

提供气象产品检验相关python程序


地面要素统计检验

<p>[TOC]</p> <pre><code class="language-python">%matplotlib inline %load_ext autoreload %autoreload 2 import pandas as pd import meteva.method as mem import meteva.base as meb import meteva.product as mpd import meteva.perspact as mps # 透视分析模块 import datetime import meteva import numpy as np import os import copy</code></pre> <h1>地面要素站点统计检验</h1> <p>在需要对长时间序列的预报数据进行检验时,如果数据量很大,且预报数据的读取非常耗时,也可以采用并行的方法来提高效率</p> <table> <thead> <tr> <th style="text-align: left;">参数</th> <th style="text-align: left;">说明</th> </tr> </thead> <tbody> <tr> <td style="text-align: left;"><strong>&lt;font face=&quot;黑体&quot; color=blue size = 5&gt;para&lt;/font&gt;</strong></td> <td style="text-align: left;">统计的参数</td> </tr> <tr> <td style="text-align: left;">&lt;font face=&quot;黑体&quot; color=blue size=5&gt;return&lt;/font&gt;</td> <td style="text-align: left;">统计量中间结果输出到文件中,函数不返回结果</td> </tr> </tbody> </table> <p><strong> 参数示例和说明</strong> </p> <h2>降水预报检验实例</h2> <pre><code class="language-python">para= { &amp;quot;mid_method&amp;quot;: meteva.method.hfmc, # 统计检验的总量计算函数, &amp;quot;grade_list&amp;quot;: [0.1,10,25,50,100], # 二分类检验所需的等级参数 &amp;quot;compare&amp;quot;: &amp;quot;&amp;gt;=&amp;quot;, # 二分类检验所需的对比方式参数 &amp;quot;begin_time&amp;quot;:datetime.datetime(2024,9,1,8), #时段开始时刻(基于起报时间) &amp;quot;end_time&amp;quot;:datetime.datetime(2024,9,3,20), #时段结束时刻(基于起报时间) &amp;quot;time_type&amp;quot;:&amp;quot;UT&amp;quot;, # 最终检验结果呈现时,采用北京时还是世界时,UT代表世界时,BT代表北京时 &amp;quot;time_step&amp;quot;: 12, # 起报时间间隔 &amp;quot;middle_result_path&amp;quot;: r&amp;quot;H:\test_data\output\mps\hfmc.h5&amp;quot;, #检验中间量数据的存储路径 &amp;quot;station_file&amp;quot;:meteva.base.station_国家站, #检验站点表的存储路径 &amp;quot;defalut_value&amp;quot;:meteva.base.IV, &amp;quot;interp&amp;quot;: meteva.base.interp_gs_nearest, &amp;quot;recover&amp;quot;:False, #False表示保留已经收集好的中间量,补齐未收集的数据,True表示删除已有的统计结果文件,重新开始收集 &amp;quot;cpu&amp;quot;:2, &amp;quot;ob_data&amp;quot;:{ &amp;quot;dir_ob&amp;quot;: r&amp;quot;I:\rc\RAIN\rain0\YYYYMMDDHH.000&amp;quot;, # 实况场数据路径 &amp;quot;hour&amp;quot;:None, &amp;quot;read_method&amp;quot;: meteva.base.io.read_stadata_from_micaps3, #读取数据的函数 &amp;quot;read_para&amp;quot;: {}, #读取数据的函数参数 &amp;quot;reasonable_value&amp;quot;: [0, 1000], #合理的观测值的取值范围,超出范围观测将被过滤掉 &amp;quot;operation&amp;quot;:meteva.base.fun.sum_of_sta, #实况数据读取后处理函数 &amp;quot;operation_para&amp;quot;: {&amp;quot;used_coords&amp;quot;: [&amp;quot;time&amp;quot;], &amp;quot;span&amp;quot;: 24}, #实况数据读取后处理参数 &amp;quot;time_type&amp;quot;: &amp;quot;BT&amp;quot;, # 数据文件中的时间类型,UT代表世界时 }, &amp;quot;fo_data&amp;quot;:{ &amp;quot;ECMWF&amp;quot;: { &amp;quot;dir_fo&amp;quot;: r&amp;quot;S:\data\grid\ECMWF_HR\APCP\YYYYMMDD\YYMMDDHH.TTT.nc&amp;quot;, # 数据路径 &amp;quot;hour&amp;quot;: [8, 20, 12], #一天中的起报时长,第一个时次,最后一个时次,时次间隔 &amp;quot;dtime&amp;quot;:[0,48,12], #检验的时效 &amp;quot;read_method&amp;quot;: meteva.base.io.read_griddata_from_nc, #读取数据的函数 &amp;quot;read_para&amp;quot;: {}, #读取数据的函数参数 &amp;quot;reasonable_value&amp;quot;: [0, 1000], #合理的预报值的取值范围,超出范围观测将被过滤掉 &amp;quot;operation&amp;quot;: meteva.base.fun.change, #预报数据读取后处理函数 &amp;quot;operation_para&amp;quot;: {&amp;quot;used_coords&amp;quot;: &amp;quot;dtime&amp;quot;, &amp;quot;delta&amp;quot;: 24}, #预报数据读取后处理参数 &amp;quot;time_type&amp;quot;: &amp;quot;BT&amp;quot;, # 预报数据时间类型是北京时,即08时起报 &amp;quot;move_fo_time&amp;quot;: 0 #是否对预报的时效进行平移,12 表示将1月1日08时的36小时预报转换成1月1日20时的24小时预报后参与对比 }, &amp;quot;SCMOC&amp;quot;: { &amp;quot;dir_fo&amp;quot;: r&amp;quot;S:\data\grid\NWFD_SCMOC\RAIN03\YYYYMMDD\YYMMDDHH.TTT.nc&amp;quot;, # 数据路径 &amp;quot;hour&amp;quot;: [8, 20, 12], #一天中的起报时长,第一个时次,最后一个时次,时次间隔 &amp;quot;dtime&amp;quot;:[3,48,3], #检验的时效 &amp;quot;read_method&amp;quot;: meteva.base.io.read_griddata_from_nc, #读取数据的函数 &amp;quot;read_para&amp;quot;: {}, #读取数据的函数参数 &amp;quot;reasonable_value&amp;quot;: [0, 1000], #合理的预报值的取值范围,超出范围观测将被过滤掉 &amp;quot;operation&amp;quot;: meteva.base.fun.sum_of_sta, # #预报数据读取后处理函数,sum_of_sta 表示在将逐3小时格点降水插值到站点后,需要将3小时降水累加成24小时降水 &amp;quot;operation_para&amp;quot;: {&amp;quot;used_coords&amp;quot;: [&amp;quot;dtime&amp;quot;], &amp;quot;span&amp;quot;: 24}, # #预报数据读取后处理参数 &amp;quot;time_type&amp;quot;: &amp;quot;BT&amp;quot;, # 预报数据时间类型是北京时,即08时起报 &amp;quot;move_fo_time&amp;quot;: 0 #是否对预报的时效进行平移,12 表示将1月1日08时的36小时预报转换成1月1日20时的24小时预报后参与对比 }, }, &amp;quot;output_dir&amp;quot;:None #观测站点合并数据的输出路径,设置为None时不输出收集数据的中间结果 } </code></pre> <h2>关于para的补充说明:</h2> <ol> <li>mid_method 参数常用的选项包括 mem.tase,mem.tmmsss,mem.hfmc等。如果要统计平均误差、平均绝对误差、均方根误差就选mem.tase;如果要计算二分类的指标,如TS、BIAS等就选择mem.hfmc; 如果要选相关系数就选mem.tmmsss,大部分情况下高空要素一般要计算距平相关系数,而非普通的相关系数。在meteva中计算距平相关系数有专门的ACC模块。</li> <li>grade_list 和compare参数只有当mid_method = mem.hfmc时才需要设置,它们是二分类检验要用到的参数</li> <li>统计形成的中间量数据文件中包含但未报仅包含begin_time 至end_time 时段内的数据,如果recover=False,它还会包含上一次运行留下来的统计数据。</li> <li>time_step参数一般用于起报时间的间隔,例如全球模式一般是12小时间隔报一次。在调试阶段,time_step也可以设置得大一些,例如1200, 这样程序会跳跃着读取部分日期的数据进行统计,用户可以根据部分数据的统计结果来计算评分和绘图,如果检验结果合理,在重新将dtime 设置为12进行统计。避免花费很长时间完成统计后,结果是错误的,则又要重新返工,浪费大量时间。 对于非常长的时间序列,time_step 也未必一定要根据实际的预报起报时间间隔来进行设置,例如时间间隔是12小时,那将time_step 设置成60小时,也可以得到很有代表性的统计结果。此处只所以设置为60而不是48或72,是考虑到后面两种设置方法不能遍历到00和12时两种起报时间。</li> <li>read_method对应的读取数据函数应该包含参数time,level,dtime,本模块的程序会自动循环采用不同的time,dtime,level参数调用read_method。read_para 中则不必包含time,dtime,level相关的内容,因为本程序会自动设置这些参数。</li> </ol> <h2>调用方法</h2> <pre><code class="language-python"># 统计rmse,me,mae 相关的中间量 mps.middle_of_score_surface(para)</code></pre> <pre><code>Waiting for all subprocesses done... All subprocesses done. 中间量拼接程序运行完毕 拼接后的中间结果已输出至H:\test_data\output\mps\hfmc.h5 总耗时:66.90529608726501</code></pre> <pre><code class="language-python">#加载中结果数据 df_mid = pd.read_hdf(para[&amp;quot;middle_result_path&amp;quot;]) print(df_mid)</code></pre> <pre><code> time dtime member grade H F M C 0 2024-09-01 08:00:00 24 ECMWF 0.1 659.0 1075.0 41.0 629.0 1 2024-09-01 08:00:00 24 ECMWF 10.0 34.0 159.0 97.0 2114.0 2 2024-09-01 08:00:00 24 ECMWF 25.0 3.0 10.0 34.0 2357.0 3 2024-09-01 08:00:00 24 ECMWF 50.0 0.0 0.0 9.0 2395.0 4 2024-09-01 08:00:00 24 ECMWF 100.0 0.0 0.0 0.0 2404.0 .. ... ... ... ... ... ... ... ... 0 2024-09-03 20:00:00 48 SCMOC 0.1 674.0 221.0 318.0 1192.0 1 2024-09-03 20:00:00 48 SCMOC 10.0 90.0 141.0 116.0 2058.0 2 2024-09-03 20:00:00 48 SCMOC 25.0 10.0 41.0 35.0 2319.0 3 2024-09-03 20:00:00 48 SCMOC 50.0 0.0 4.0 10.0 2391.0 4 2024-09-03 20:00:00 48 SCMOC 100.0 0.0 0.0 0.0 2405.0 [180 rows x 8 columns]</code></pre> <pre><code class="language-python">#根据中间量结果绘制误差曲线 result = mps.score_df(df_mid,mem.ts,g = [&amp;quot;grade&amp;quot;,&amp;quot;member&amp;quot;,&amp;quot;dtime&amp;quot;],plot =&amp;quot;line&amp;quot;,ncol = 3,sup_title = &amp;quot;TS&amp;quot;)</code></pre> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=6382dbf030757fd95e2457975b4a2a65&amp;amp;file=file.png" alt="" /></p> <p>上面是对比不同模式的ts的实现方式。如果需要对比模式对副高的预报性能,则可以用二分类检验指标来实现</p> <pre><code class="language-python">#根据中间量结果绘制误差曲线 result = mps.score_df(df_mid,mem.bias,g = [&amp;quot;grade&amp;quot;,&amp;quot;member&amp;quot;,&amp;quot;dtime&amp;quot;],plot =&amp;quot;line&amp;quot;,ncol = 3,sup_title = &amp;quot;BIAS&amp;quot;) </code></pre> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=737836e0963c1e2953cfa45ac598208a&amp;amp;file=file.png" alt="" /></p> <h2>风向风速预报检验实例</h2> <pre><code class="language-python"> def read_ob_wind(path): speed = meteva.base.read_stadata_from_micaps1_2_8(path,column=meteva.base.m2_element_column.风速) angle = meteva.base.read_stadata_from_micaps1_2_8(path,column=meteva.base.m2_element_column.风向) if speed is not None and angle is not None: speed = meteva.base.sele_by_para(speed,value=[0,100]) wind = meteva.base.speed_angle_to_wind(speed,angle) return wind else: return None para_wind= { &amp;quot;base_on&amp;quot;: &amp;quot;foTime&amp;quot;, # 程序运行时段范围是基于起报时间 &amp;quot;mid_method&amp;quot;: meteva.method.na_uv, # 统计检验的总量计算函数, &amp;quot;grade_list&amp;quot;: None, # 二分类检验所需的等级参数 &amp;quot;compare&amp;quot;: None, # 二分类检验所需的对比方式参数 &amp;quot;begin_time&amp;quot;:datetime.datetime(2024,9,1,8), &amp;quot;end_time&amp;quot;:datetime.datetime(2024,9,3,20), &amp;quot;time_type&amp;quot;:&amp;quot;BT&amp;quot;, # 最终检验结果呈现时,采用北京时还是世界时,UT代表世界时,BT代表北京时 &amp;quot;time_step&amp;quot;: 12, # 起报时间间隔 &amp;quot;middle_result_path&amp;quot;: r&amp;quot;H:\test_data\output\mps\na.h5&amp;quot;, #检验中间量数据的存储路径 &amp;quot;station_file&amp;quot;:meteva.base.station_国家站, #检验站点表的存储路径 &amp;quot;defalut_value&amp;quot;:meteva.base.IV, &amp;quot;interp&amp;quot;: meteva.base.interp_gs_nearest, &amp;quot;recover&amp;quot;:False, #False表示保留已经收集好的中间量,补齐未收集的数据,True表示删除已有的统计结果文件,重新开始收集 &amp;quot;cpu&amp;quot;:6, &amp;quot;ob_data&amp;quot;:{ &amp;quot;dir_ob&amp;quot;: r&amp;quot;\\10.20.22.27\rc\WIND\w2mi0\YYYYMMDDHH.000&amp;quot;, # 实况场数据路径 &amp;quot;hour&amp;quot;:None, &amp;quot;read_method&amp;quot;: read_ob_wind, #读取数据的函数 &amp;quot;read_para&amp;quot;: {}, #读取数据的函数参数 &amp;quot;reasonable_value&amp;quot;: None, &amp;quot;operation&amp;quot;:None, #实况数据读取后处理函数 &amp;quot;operation_para&amp;quot;: {}, #实况数据读取后处理参数 &amp;quot;time_type&amp;quot;: &amp;quot;BT&amp;quot;, # 数据文件中的时间类型,UT代表世界时 }, &amp;quot;fo_data&amp;quot;:{ &amp;quot;ECMWF&amp;quot;: { &amp;quot;dir_fo&amp;quot;: r&amp;quot;S:\data\grid\ECMWF_HR\WIND_10M\YYYYMMDD\YYMMDDHH.TTT.nc&amp;quot;, # 数据路径 &amp;quot;hour&amp;quot;: [8, 20, 12], &amp;quot;dtime&amp;quot;:[12,240,12], #检验的时效 &amp;quot;read_method&amp;quot;: meteva.base.io.read_griddata_from_nc, #读取数据的函数 &amp;quot;read_para&amp;quot;: {}, #读取数据的函数参数 &amp;quot;reasonable_value&amp;quot;: None, &amp;quot;operation&amp;quot;: None, #预报数据读取后处理函数 &amp;quot;operation_para&amp;quot;: {}, #预报数据读取后处理参数 &amp;quot;time_type&amp;quot;: &amp;quot;BT&amp;quot;, # 预报数据时间类型是北京时,即08时起报 &amp;quot;move_fo_time&amp;quot;: 0 #是否对预报的时效进行平移,12 表示将1月1日08时的36小时预报转换成1月1日20时的24小时预报后参与对比 }, &amp;quot;SCMOC&amp;quot;: { &amp;quot;dir_fo&amp;quot;: r&amp;quot;S:\data\grid\NWFD_SCMOC\WIND\10M_ABOVE_GROUND\YYYYMMDD\YYMMDDHH.TTT.nc&amp;quot;, &amp;quot;hour&amp;quot;: [8, 20, 12], &amp;quot;dtime&amp;quot;:[12,240,12], &amp;quot;read_method&amp;quot;: meteva.base.io.read_griddata_from_nc, &amp;quot;read_para&amp;quot;: {}, &amp;quot;reasonable_value&amp;quot;: None, &amp;quot;operation&amp;quot;: None, &amp;quot;operation_para&amp;quot;: {}, &amp;quot;time_type&amp;quot;: &amp;quot;BT&amp;quot;, &amp;quot;move_fo_time&amp;quot;: 0 }, }, &amp;quot;output_dir&amp;quot;:None #观测站点合并数据的输出路径,设置为None时不输出收集数据的中间结果 }</code></pre> <pre><code class="language-python"># 统计rmse,me,mae 相关的中间量 mps.middle_of_score_surface(para_wind)</code></pre> <pre><code>ECMWF2024年09月01日08时起报的检验中间量已存在 ECMWF2024年09月01日20时起报的检验中间量已存在 ECMWF2024年09月02日08时起报的检验中间量已存在 ECMWF2024年09月02日20时起报的检验中间量已存在 ECMWF2024年09月03日08时起报的检验中间量已存在 ECMWF2024年09月03日20时起报的检验中间量已存在 SCMOC2024年09月01日08时起报的检验中间量已存在 SCMOC2024年09月01日20时起报的检验中间量已存在 SCMOC2024年09月02日08时起报的检验中间量已存在 SCMOC2024年09月02日20时起报的检验中间量已存在 SCMOC2024年09月03日08时起报的检验中间量已存在 SCMOC2024年09月03日20时起报的检验中间量已存在 [] 未指定需要并行的参数列表 Waiting for all subprocesses done... All subprocesses done. 中间量拼接程序运行完毕 拼接后的中间结果已输出至H:\test_data\output\mps\na.h5 总耗时:0.03599262237548828</code></pre> <pre><code class="language-python">#加载中结果数据 df_mid = pd.read_hdf(para_wind[&amp;quot;middle_result_path&amp;quot;]) print(df_mid)</code></pre> <pre><code> time dtime member T ACZ ACD ACS 0 2024-09-01 08:00:00 12 ECMWF 2407.0 322.0 717.0 1049.0 0 2024-09-01 08:00:00 12 SCMOC 2407.0 393.0 706.0 1354.0 0 2024-09-01 08:00:00 24 ECMWF 2408.0 347.0 770.0 1189.0 0 2024-09-01 08:00:00 24 SCMOC 2408.0 441.0 774.0 1482.0 0 2024-09-01 08:00:00 36 ECMWF 2408.0 282.0 748.0 975.0 .. ... ... ... ... ... ... ... 0 2024-09-03 20:00:00 216 SCMOC 2408.0 266.0 541.0 1168.0 0 2024-09-03 20:00:00 228 ECMWF 2408.0 140.0 515.0 780.0 0 2024-09-03 20:00:00 228 SCMOC 2408.0 247.0 504.0 1228.0 0 2024-09-03 20:00:00 240 ECMWF 2408.0 133.0 479.0 724.0 0 2024-09-03 20:00:00 240 SCMOC 2408.0 285.0 571.0 1169.0 [240 rows x 7 columns]</code></pre> <pre><code class="language-python">#根据中间量结果绘制误差曲线 result = mps.score_df(df_mid,mem.acd_uv,g = [&amp;quot;member&amp;quot;,&amp;quot;dtime&amp;quot;],plot =&amp;quot;line&amp;quot;,ncol = 3,title = &amp;quot;风向预报准确率&amp;quot;)</code></pre> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=a11a4a0f8b81d6141769abbe850dfb94&amp;amp;file=file.png" alt="" /></p> <pre><code class="language-python">#根据中间量结果绘制误差曲线 result = mps.score_df(df_mid,mem.acs_uv,g = [&amp;quot;member&amp;quot;,&amp;quot;dtime&amp;quot;],plot =&amp;quot;line&amp;quot;,ncol = 3,title = &amp;quot;风速预报准确率&amp;quot;)</code></pre> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=ef6ebe89c01ea2cc6a584a9fe196a2fb&amp;amp;file=file.png" alt="" /></p> <pre><code class="language-python"></code></pre> <h1>并行任务下sbatch脚本</h1> <p>在大型机上如果使用并行方式运行mps.middle_of_score程序(即参数cpu大于1)时务必采用sbatch方式提交作业,否则可能导致登录节点卡顿。 下面是提交作业的sbatch脚本,其中:</p> <ul> <li>参数N=1表示只采用一个计算几点(其中包含多个cpu核心)。</li> <li>mem=64G表示计算所需的内存。如果统计中国附近区域中尺度模式一整年的数据,每天2个起报时次,每个起报时次10个预报时效,每个时效20层数据,para[&quot;step&quot;]设置为5,mem需要设置在16G以上。如果统计全球模式1整年的数据,每天2个起报时次,每个起报时间10个预报时效,每个时效有20个层次,para[&quot;step&quot;]参数设置为5,mem需要设置在128以上。</li> <li>参数p normal 表示用并行方式执行。</li> </ul> <pre><code class="language-python">#!/bin/bash #SBATCH --comment GRAPES #SBATCH --wckey=105-02 #SBATCH -J GRAPES #SBATCH -N 1 #SBATCH --mem=64G #SBATCH --ntasks-per-node=64 #SBATCH -p normal #SBATCH -t 72:00:00 #SBATCH -o ./out.print.%j.txt #SBATCH -e ./out.err.%j.txt #set runtime environment variables unset SLURM_MEM_PER_CPU #some shell commands ulimit -c unlimited ulimit -s unlimited #export QT_DEBUG_PLUGINS=1 export QT_QPA_PLATFORM='offscreen' python hgt_data_prepare.py </code></pre> <pre><code class="language-python"></code></pre>

页面列表

ITEM_HTML