数据预处理
<p>[TOC]</p>
<p>在基于预报检验层的功能函数开展检验时,通常需要将分散在逐个文件中的数据读取、拼接、匹配合并成一个DataFrame。将整合好的DataFrame输出到一个文件中,在后续开展中也可以反复使用,相比于重新读取逐个文件要便捷高效得多。基于meteva化模块化的编程思路,虽然在数据整个的过程中代码量也必将多,但框架结构是固定可复用的,用户通常只需把一些已有代码复制过来,修改一下文件路径、循环步长、读取函数等等语句即可完整数据收集模块的开发工作。同时这种模块化的特征使得它有被进一步封装的潜力,为此我们进一步将数据整合相关的模块进行了封装,形成了一个函数,在这个函数中只要设置合理的参数就可以一句话完整数据预处理工作。
这样做有2个好处:</p>
<ol>
<li>原先收集数据需要编写代码,之后只需配置相应的参数即可。配置优于研发带来的好处就是不需要走研发流程就可以完成一定的定制逻辑。 </li>
<li>数据收集模块中并不需要每次都把所有数据取一遍再整合,只需读入最近更新的数据即可,这样可以提高运行效率。 </li>
</ol>
<p>但也需要注意它的缺点:</p>
<ol>
<li>数据整合模块只能使用于一些常见数据的读取整合问题,有些特殊格式文件还是要另外编程读取 </li>
<li>为了扩展数据整合模块的适应能力,其配置参数的复杂性逐步加大,此时准确理解每个配置参数的含义也是会成为一项工作负担。基于这个原因,数据整合模块的不是万能的,未来也不会无限制的扩展该模块的功能。 </li>
</ol>
<h1>数据预处理</h1>
<p><strong>prepare_dataset(para)</strong><br />
根据字典型的配置参数对数据进行预处理 </p>
<p><strong>参数说明:</strong><br />
<strong>para</strong>: 数据下载配置参数,以下结合系统中集成的一个示例 mpd.application.data_prepare.para_example进行阐述<br />
<strong>return</strong>: 无 </p>
<pre><code class="language-python">import meteva
import meteva.base as meb
import meteva.product as mpd
import datetime
para_example= {
&quot;base_on&quot;: &quot;foTime&quot;, # 程序运行时段范围是基于起报时间还是预报时间(foTime 表示基于起报时间,obTime 表示基于实况时间)
&quot;begin_time&quot;:datetime.datetime.now() - datetime.timedelta(days =7),
&quot;end_time&quot;:datetime.datetime.now(),
&quot;time_type&quot;: &quot;BT&quot;, # 程序运行时段是基于北京时还是世界时,BT表示北京时,UT表示世界时
&quot;how_fo&quot;:&quot;outer&quot;, #不同模式数据的合并逻辑,outer 表示取不同模式的时间、时效并集, inner 表示取不同模式的时间时效交集
&quot;station_file&quot;:r&quot;H:\task\other\202009-veri_objective_method\sta_info.m3&quot;,
&quot;defalut_value&quot;:0,
&quot;hdf_file_name&quot;:&quot;last_week_data.h5&quot;,
&quot;interp&quot;: meteva.base.interp_gs_nearest,
&quot;ob_data&quot;:{
&quot;dir_ob&quot;: r&quot;Z:\data\surface\jiany_rr\r1\YYMMDDHH.000&quot;,
&quot;hour&quot;:None,
&quot;read_method&quot;: meteva.base.io.read_stadata_from_micaps3,
&quot;read_para&quot;: {},
&quot;reasonable_value&quot;: [0, 1000],
&quot;operation&quot;:meteva.base.fun.sum_of_sta,
&quot;operation_para&quot;: {&quot;used_coords&quot;: [&quot;time&quot;], &quot;span&quot;: 24},
&quot;time_type&quot;: &quot;BT&quot;, #数据文件是以北京时还是世界时命名,BT表示北京时,UT表示世界时
},
&quot;fo_data&quot;:{
&quot;ECMWF&quot;: {
&quot;dir_fo&quot;: r&quot;O:\data\grid\ECMWF_HR\APCP\YYYYMMDD\YYMMDDHH.TTT.nc&quot;,
&quot;hour&quot;:[8,20,12],
&quot;dtime&quot;:[0,240,12],
&quot;read_method&quot;: meteva.base.io.read_griddata_from_nc,
&quot;read_para&quot;: {},
&quot;reasonable_value&quot;: [0, 1000],
&quot;operation&quot;: meteva.base.fun.change,
&quot;operation_para&quot;: {&quot;used_coords&quot;: &quot;dtime&quot;, &quot;delta&quot;: 24},
&quot;time_type&quot;: &quot;BT&quot;, #数据文件是以北京时还是世界时命名,BT表示北京时,UT表示世界时
&quot;move_fo_time&quot;: 12
},
&quot;SCMOC&quot;: {
&quot;dir_fo&quot;: r&quot;O:\data\grid\NWFD_SCMOC\RAIN03\YYYYMMDD\YYMMDDHH.TTT.nc&quot;,
&quot;hour&quot;: [8, 20,12],
&quot;dtime&quot;:[3,240,3],
&quot;read_method&quot;: meteva.base.io.read_griddata_from_nc,
&quot;read_para&quot;: {},
&quot;reasonable_value&quot;: [0, 1000],
&quot;operation&quot;: meteva.base.fun.sum_of_sta,
&quot;operation_para&quot;: {&quot;used_coords&quot;: [&quot;dtime&quot;], &quot;span&quot;: 24},
&quot;time_type&quot;: &quot;BT&quot;, #数据文件是以北京时还是世界时命名,BT表示北京时,UT表示世界时
&quot;move_fo_time&quot;: 0
},
},
&quot;output_dir&quot;:r&quot;H:\task\other\202009-veri_objective_method&quot;
}</code></pre>
<pre><code class="language-python"># 以下结合上述para_example 对参数中的每个关键词的含义进行说明如下表:</code></pre>
<table>
<thead>
<tr>
<th style="text-align: left;">para字典参数中各关键字</th>
<th style="text-align: left;"></th>
<th style="text-align: left;"></th>
<th style="text-align: left;">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;"><strong>base_on</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">程序运行时段范围是基于起报时间还是预报时间(foTime 表示基于起报时间,obTime 表示基于实况时间)</td>
</tr>
<tr>
<td style="text-align: left;"><strong>begin_time</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">拼接后的数据保护的观测和预报数据的起始时间,在业务中如果是需要对一段固定起止时段的数据进行检验,则它应该设置为一个固定值,如果业务检验要准备的数据是滚动变化的,则它可根据datetime.datetime.now()函数来设置,如上例所示。</td>
</tr>
<tr>
<td style="text-align: left;"><strong>end_time</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">拼接后数据的观测和预报数据的结束时间。<font face="黑体" color=red size =3>考虑到程序运行较为耗时,建议可以先设置一个较短的时间范围,测试程序是否能正常运行,再根据实际需要设置时段范围</font></td>
</tr>
<tr>
<td style="text-align: left;"><strong>time_type</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">程序运行时段是基于北京时还是世界时,BT表示北京时,UT表示世界时,也可以说是上面的时段参数 begin_time和end_time对应的时间类型,同时也是最终收集的数据的time列的时间类型</td>
</tr>
<tr>
<td style="text-align: left;"><strong>how_fo</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">不同模式数据的合并逻辑,outer 表示取不同模式的时间、时效并集, inner 表示取不同模式的时间时效交集,例如cma-gfs模式有0-240小时时效预报,cma-meso只有0-72小时时效,如果how_fo="outer",则收集的数据包含0-240小时时效,cma-meso模式的缺失部分用99999填充,如果how_fo = "inner",则收集的数据只有0-72小时时效的部分</td>
</tr>
<tr>
<td style="text-align: left;"><strong>station_file</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">micaps第3类格式的站点表文件</td>
</tr>
<tr>
<td style="text-align: left;"><strong>defalut_value</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">数据文件中不包含的站点将被设置为default_value</td>
</tr>
<tr>
<td style="text-align: left;"><strong>hdf_file_name</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">拼接后的文件,以及匹配合并后的文件的文件名(不带文件夹部分)</td>
</tr>
<tr>
<td style="text-align: left;"><strong>interp</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">网格数据到站点数据插值的方法</td>
</tr>
<tr>
<td style="text-align: left;"><strong>ob_data</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">观测数据的参数设置</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>dir_ob</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">拼接前观测数据文件路径的通配模型,具体可参考上述代码中的示例</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>hour</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">观测数据文件中包含的hour_of_day (北京时)的集合,当设置为None时,程序会遍历0-23判断每个各小时的文件是否存在并读取,如果只有(只需)08时和20时的数据文件,既可以将该参数设置为None,也可以将该参数设置为[8,20,12],方括号里分别是起止和间隔</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>read_method</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">读取观测文件的函数方法,根据站点数据文件格式来选择具体的读取方法,可选的包括<a href="https://www.showdoc.com.cn/meteva?page_id=3975601856475911">站点数据读取</a>模块中的各类函数。如果站点数据格式是采用hdf格式存储的sta_data,则该参数应该设置为pd.read_hdf。注意设置该参数时只需保留函数名称,不要加()号</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>read_para</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">上述read_method的参数中除了station,level,time,dtime,data_name,show 之外的其它参数,例如当数据文件时micaps1类数据,要从中读取温度要素,则除了设置"read_method":meb.read_stadata_from_micaps1_2_8之外,还需要设置column参数才能进一步明确调研函数的方式。此时,read_para 参数可设置为{"column":meb.m1_element_column.温度}, 当读取过程不需要带额外的参数时,则该参数设置为{},如上面代码中的示例</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>reasonable_value</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">从观测数据中读取的数据合理取值范围,超出范围的将会被删除</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>operation</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">如果读入的观测数据就是预报检验对标的数据,则该参数设置为None。 但有时读入的数据还不是预报对标的实况,举例1,读入的数据是逐小时的温度,但预报的是24小时变温,此时需要将温度实况转换为变温实况, 这时该参数就需要设置为 meb.change; 举例2, 读取的是逐小时的降水,但检验的是24小时的累计降水量,此时需要将1小时降水累加成24小时的降水量,此时该参数应该设置为meb.sum_of_sta</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>operation_para</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">如果读入的观测数据就是预报检验对标的数据,则该参数设置为{}。 但有时读入的数据还不是预报对标的实况,举例1,读入的数据是逐小时的温度,但预报的是24小时变温,此时需要将温度实况转换为变温实况, 这时operation参数就需要设置为 meb.change,而该参数这需要设置为{"used_coords": "time", "delta": 24}; 举例2, 读取的是逐小时的降水,但检验的是24小时的累计降水量,此时需要将1小时降水累加成24小时的降水量,此时operation参数应该设置为meb.sum_of_sta,该参数则应设置为{"used_coords": ["time"], "span": 24}</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>time_type</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">观测数据的时间类型,北京时间为"BT",世界时为"UT"</td>
</tr>
<tr>
<td style="text-align: left;"><strong>fo_data</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">预报数据的参数设置</td>
</tr>
<tr>
<td style="text-align: left;"><strong>数据名称</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">预报数据的名称,它将出现在匹配合并后的sta_data的数据列名称中</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>dir_ob</strong></td>
<td style="text-align: left;">拼接前观测数据文件路径的通配模型,具体可参考上述代码中的示例</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>hour</strong></td>
<td style="text-align: left;">预报数据文件中包含起报时间的hour_of_day (北京时)的集合,当设置为None时,程序会遍历0-23判断每个各小时的文件是否存在并读取,如果只有(只需)08时和20时的数据文件,既可以将该参数设置为None,也可以将该参数设置为[8,20,12],方括号里分别是起止和间隔,后一种参数设置方法运行效率会高一些</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>read_method</strong></td>
<td style="text-align: left;">读取观测文件的函数方法,根据站点数据文件格式来选择具体的读取方法,可选的包括<a href="https://www.showdoc.com.cn/meteva?page_id=3975601856475911">站点数据读取</a>模块中的各类函数,也可以是<a href="https://www.showdoc.com.cn/meteva?page_id=3975601833484385">网格数据读取</a>模块中的各类函数。如果站点数据格式是采用hdf格式存储的sta_data,则该参数应该设置为pd.read_hdf。注意设置该参数时只需保留函数名称,不要加()号</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>read_para</strong></td>
<td style="text-align: left;">上述read_method的参数中除了station,level,time,dtime,data_name,show 之外的其它参数</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>reasonable_value</strong></td>
<td style="text-align: left;">从观测数据中读取的数据合理取值范围,超出范围的将会被删除</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>operation</strong></td>
<td style="text-align: left;">如果读入的观测预报数据就是观测检验对标的数据,则该参数设置为None。 但有时读入的数据还不是观测对标的物理量,举例1,读入的数据是逐小时的温度预报,但是检验的是24小时变温,此时需要将温度预报转换为变温预报, 这时该参数就需要设置为 meb.change; 举例2, 读取的是逐小时的降水预报,但检验的是24小时的降水量预报,此时需要将1小时降水预报累加成24小时的降水量预报,此时该参数应该设置为meb.sum_of_sta,举例3,读入的数据是随时效逐渐累加的降水量预报,检验对象是24小时降水量,则该参数应该设置为 meb.change</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>operation_para</strong></td>
<td style="text-align: left;">如果读入的预报数据就是观测检验对标的数据,则该参数设置为{}。 但有时读入的预报数据还不是检验对象,在上述两个举例中,举例1,该参数应设置为{"used_coords": "dtime", "delta": 24}; 举例2, 该参数则应设置为{"used_coords": ["dtime"], "span": 24},举例3,该参数应该设置为{"used_coords":"dtime","delta",24}</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>time_type</strong></td>
<td style="text-align: left;">观测数据的时间类型,北京时间为"BT",世界时为"UT"</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"><strong>move_fo_time</strong></td>
<td style="text-align: left;">是否平移预报的起报时间,例如为了将36小时时效的ECMWF模式预报和24小时时效的SCMOC网格预报对齐,则ECMWF模式对应的参数应该设置为12, 而SCMOC对应的参数应该设置为0</td>
</tr>
<tr>
<td style="text-align: left;"><strong>output_dir</strong></td>
<td style="text-align: left;"></td>
<td style="text-align: left;"></td>
<td style="text-align: left;">匹配合并后的数据的存放目录由output_dir +hdf_file_name 生成</td>
</tr>
</tbody>
</table>
<pre><code class="language-python">mpd.prepare_dataset(para_example) # 运行过程中会打印不存在的文件信息或者读取错误的信息 </code></pre>
<pre><code>Z:\data\surface\jiany_rr\r1\20092900.000does not exist
Z:\data\surface\jiany_rr\r1\20092901.000does not exist
Z:\data\surface\jiany_rr\r1\20092902.000does not exist
...
O:\data\grid\NWFD_SCMOC\RAIN03\20200928\20092820.240.nc does not exist
H:\test_data\output\mpd\application\rain24/last_week_data.h5
8
0% combined
1% combined
2% combined
4% combined
5% combined
...
95% combined
97% combined
98% combined
10.558505773544312
success combined data to H:\task\other\202009-veri_objective_method/last_week_data/last_week_data.h5</code></pre>
<h1>降水预报预处理示例</h1>
<p>一下是一个在linux服务器中对降水预报和实况进行预处理的程序示例,其中包含每项参数的说明</p>
<pre><code class="language-python">import sys
sys.path.append(&quot;/g5/liuch/code/python&quot;) #加载读取站点数据的脚步
from read_stadata import read_stadata_from_rawsh,rawsh_element_column #加载读取站点数据的函数
import meteva.base as meb
import meteva.product as mpd
from reki.format.grib.eccodes import load_field_from_file
import numpy as np
import datetime
#通过reki读取grib数据的函数
def read_grib_by_reki(path,value_name):
field_values = load_field_from_file(path, parameter=value_name)
grd = meb.xarray_to_griddata(field_values,level_dim=&quot;single&quot;,lat_dim=&quot;latitude&quot;,lon_dim=&quot;longitude&quot;)
return grd
#读取24小时降水量的函数
def read_obs(time):
if time.hour ==0:
dir1 = r&quot;/g6/op_vfy/MUVOS/obs/station/sl/rainnew/rain_24/YYYYMM/rain24_YYYYMMDDHH.dat&quot;
else:
dir1 = r&quot;/g6/op_vfy/MUVOS/obs/station/sl/rainnew/rain_24-12/YYYYMM/rain24_YYYYMMDDHH.dat&quot;
path = meb.get_path(dir1,time)
sta = meb.read_stadata_from_csv(path,columns=[&quot;id&quot;,&quot;lon&quot;,&quot;lat&quot;,&quot;OBS&quot;],member_list=[&quot;OBS&quot;],time = time,dtime=0)
return sta
para= {
&quot;base_on&quot;:&quot;foTime&quot;, #起止时段参数是基于起报时间
&quot;begin_time&quot;: datetime.datetime(2023,8,1,0), #起始时间
&quot;end_time&quot;: datetime.datetime(2023,8,3,0), #结束时间
&quot;time_type&quot;:&quot;UT&quot;, #程序运行时段是基于世界时,输出结果中的time列也是世界时
&quot;how_fo&quot;:&quot;outer&quot;,
&quot;station_file&quot;:meb.station_国家站, #站点表的文件路径
&quot;defalut_value&quot;:999999, #缺测站点赋值为999999
&quot;interp&quot;: meb.interp_gs_nearest, #采用邻近点插值方案将预报场插值到检验站点
&quot;hdf_file_name&quot;:&quot;rain24h_update12h_station2k.h5&quot;, #预处理好的数据存储的文件名
&quot;ob_data&quot;:{
&quot;dir_ob&quot;: None, #下面的read_obs函数已经集成了文件路径,所以此处只需填写None
&quot;hour&quot;: None, #尝试读取所有可能的小时
&quot;read_method&quot;: read_obs, #通过上文自定义的函数read_obs读取站点数据
&quot;read_para&quot;: {},
&quot;reasonable_value&quot;: [0, 1000], #过滤掉取值不在0-1000mm范围的样本
&quot;operation&quot;:None, #读取的数据已经是24小时降水,不用额外的计算
&quot;operation_para&quot;:{},
&quot;time_type&quot;: &quot;UT&quot;, #实况数据文件的时间类型是世界时
},
&quot;fo_data&quot;:{
&quot;CMA_MESO_3KM&quot;: {
# 3km模式的文件路径COM&gt;MDATA 中间有一个&gt;是因为COMMDATA包含了通配符MM,不加&gt;会出错
&quot;dir_fo&quot;: r&quot;/g5/rmf_xp/COM&gt;MDATA/GRAPES3km_OPGMF/YYYYMMDDHH/rmf.hgra.YYYYMMDDHHTTT.grb2&quot;,
&quot;hour&quot;: [0, 12, 12], #起报时次【最小值,最大值,间隔】, 它是基于para[&quot;time_type&quot;] 指定的时间类型来定的,而不是根据预报文件的时间类型来定
&quot;dtime&quot;: [0, 72, 12], #时效的【最小值,最大值,间隔】
&quot;reasonable_value&quot;: [0, 1000], #过滤掉取值不在0-1000mm范围的样本
&quot;read_method&quot;: read_grib_by_reki, #通过上文自定义的read_grib_by_reki函数从文件中读取数据
&quot;read_para&quot;: {&quot;value_name&quot;: &quot;rain&quot;}, #调用read_grib_by_reki所需的参数
&quot;operation&quot;: meb.change, #因为读取的数据是累计降水量,需要通过meb.change函数将其转换位rain24
&quot;operation_para&quot;: {&quot;delta&quot;:24,&quot;used_coords&quot;:&quot;dtime&quot;}, #change函数的参数
&quot;move_fo_time&quot;: 0, #不需要和后处理订正产品对比,不需要将模式平移,因此平移量设置为0
&quot;time_type&quot;: &quot;UT&quot;, #预报时间的时间类型是世界时
},
&quot;CMA_MESO_1KM&quot;: {
&quot;dir_fo&quot;: r&quot;/g5/rmf_xp/huanglp/work2024/BatchTest/China1km1hrGrib2/YYYYMMDDHH/gmf.gra.YYYYMMDDHHTTT00.grb2&quot;, # 1km模式的文件路径
&quot;hour&quot;: [0, 12, 12], #起报时次【最小值,最大值,间隔】, 它是基于para[&quot;time_type&quot;] 指定的时间类型来定的,而不是根据预报文件的时间类型来定
&quot;dtime&quot;: [0, 72, 12], #时效的【最小值,最大值,间隔】
&quot;reasonable_value&quot;: [0, 1000], #过滤掉取值不在0-1000mm范围的样本
&quot;read_method&quot;: read_grib_by_reki, #通过上文自定义的read_grib_by_reki函数从文件中读取数据
&quot;read_para&quot;: {&quot;value_name&quot;: &quot;rain&quot;}, #调用read_grib_by_reki所需的参数
&quot;operation&quot;: meb.change, #因为读取的数据是累计降水量,需要通过meb.change函数将其转换位rain24
&quot;operation_para&quot;: {&quot;delta&quot;: 24, &quot;used_coords&quot;: &quot;dtime&quot;}, #change函数的参数
&quot;move_fo_time&quot;: 0, #不需要和后处理订正产品对比,不需要将模式平移,
&quot;time_type&quot;: &quot;UT&quot;, #预报时间的时间类型是世界时
},
},
&quot;output_dir&quot;:r&quot;/g5/liuch/data/veri/test&quot;
}</code></pre>
<h1>风场预报预处理实例</h1>
<p>一下是一个在linux服务器中对10m风预报和实况进行预处理的程序示例,其中包含每项参数的说明</p>
<pre><code class="language-python">import sys
import pandas as pd
sys.path.append(&quot;/g5/liuch/code/python&quot;)
from read_stadata import read_stadata_from_rawsh,rawsh_element_column
import meteva.base as meb
import meteva.product as mpd
from reki.format.grib.eccodes import load_field_from_file
import datetime
#读取风向风速,并转换成u,v
def read_uv_from_rawsh(path):
sta_angle = read_stadata_from_rawsh(path,column = rawsh_element_column.风向)
sta_speed = read_stadata_from_rawsh(path,column = rawsh_element_column.风速)
sta_wind = meb.speed_angle_to_wind(sta_speed,sta_angle)
return sta_wind
#读取u,v风
def read_wind_by_reki(path):
u10m = load_field_from_file(path, parameter=&quot;u10m&quot;)
grd_u = meb.xarray_to_griddata(u10m,level_dim=&quot;single&quot;,lat_dim=&quot;latitude&quot;,lon_dim=&quot;longitude&quot;)
v10m = load_field_from_file(path, parameter=&quot;v10m&quot;)
grd_v = meb.xarray_to_griddata(v10m,level_dim=&quot;single&quot;,lat_dim=&quot;latitude&quot;,lon_dim=&quot;longitude&quot;)
grd_wind = meb.u_v_to_wind(grd_u,grd_v)
return grd_wind
para= {
&quot;base_on&quot;:&quot;foTime&quot;, #起止时段参数是基于起报时间
&quot;begin_time&quot;: datetime.datetime(2023,8,1,0), #起始时间
&quot;end_time&quot;: datetime.datetime(2023,8,1,0), #结束时间
&quot;time_type&quot;: &quot;UT&quot;, # 程序运行时段是基于世界时,输出结果中的time列也是世界时
&quot;station_file&quot;:meb.station_国家站, #站点表的文件路径
&quot;defalut_value&quot;:999999, #缺测站点赋值为999999
&quot;interp&quot;: meb.interp_gs_linear, #采用双线性插值方案将预报场插值到检验站点
&quot;hdf_file_name&quot;:&quot;wind_2min_update12h_station2k.h5&quot;, #预处理好的数据存储的文件名
&quot;ob_data&quot;:{
&quot;dir_ob&quot;: r&quot;/g6/op_vfy/MUVOS/obs/station/sl/rawsh/YYYYMM/rawsh1_YYYYMMDDHH.dat&quot;, #实况文件路径模板
&quot;hour&quot;: [0, 12, 12], #读取00和12时的实况
&quot;read_method&quot;: read_uv_from_rawsh, #通过上文自定义的函数read_uv_from_rawsh读取站点数据
&quot;read_para&quot;: {},
&quot;reasonable_value&quot;: [-100, 100], #过滤掉取值不在-100 - 100m/s范围的样本
&quot;operation&quot;: None, #读取的数据已经是u,v风
&quot;operation_para&quot;: {},
&quot;time_type&quot;: &quot;UT&quot;, #实况数据文件的时间类型是世界时
},
&quot;fo_data&quot;:{
&quot;CMA_MESO_1KM&quot;: {
&quot;dir_fo&quot;: r&quot;/g5/rmf_xp/huanglp/work2024/BatchTest/China1km1hrGrib2/YYYYMMDDHH/gmf.gra.YYYYMMDDHHTTT00.grb2&quot;, # 1km模式的文件路径
&quot;hour&quot;: [0, 12, 12], #起报时次【最小值,最大值,间隔】, 它是基于para[&quot;time_type&quot;] 指定的时间类型来定的,而不是根据预报文件的时间类型来定
&quot;dtime&quot;: [0, 72, 3], #时效的【最小值,最大值,间隔】
&quot;reasonable_value&quot;: [-100, 100], #过滤掉取值不在-100 - 100m/s范围的样本
&quot;read_method&quot;: read_wind_by_reki, #通过上文自定义的read_wind_by_reki函数从文件中读取数据
&quot;read_para&quot;: {},
&quot;operation&quot;: None,
&quot;operation_para&quot;: {},
&quot;move_fo_time&quot;: 0,
&quot;time_type&quot;: &quot;UT&quot;, #预报时间的时间类型是世界时
},
},
&quot;output_dir&quot;:r&quot;/g5/liuch/data/veri/test/&quot; #结果输出的文件夹
}</code></pre>