网格数据
<p>[TOC]</p>
<pre><code class="language-python">%matplotlib inline
%load_ext autoreload
%autoreload 2
import meteva.base as meb
import numpy as np
import datetime
import xarray as xr</code></pre>
<p><strong><font face="黑体" color=black size = 5>网格信息类</font></strong>
为了方便在程序中共享网格设置,本模块中将网格信息封装成一个grid类变量。它包含成员、层次、时间、时效、纬度、经度等六个维度的坐标信息,其中经度、纬度、时间这三个维度记录起始值和间距,成员、层次、时效这三个维度以列表形式记录所有值。<br />
对于不熟悉MetEva的人来说,网格信息类变量和网格数据变量容易混淆,其实它们的关系很好理解,它们就好比是房子图纸和房子本身的关系。 我们可以根据房子的图纸,填充物料变成房子,这个功能就是下面介绍的 meb.grid_data函数,也可根据房子本身绘制出图纸,这就是下面要介绍的 meb.get_grid_from_data函数。</p>
<h1>初始化网格信息类变量</h1>
<p><strong><font face="黑体" color=blue size = 5>class grid</font></strong><br />
__init__(self,glon, glat, gtime=None, dtime_list=None,level_list=None,member_list = None) </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><font face="黑体" color=blue size = 5>glon</font></strong></td>
<td style="text-align: left;">东西向网格信息:[起始经度,终止经度,经向间隔]</td>
</tr>
<tr>
<td style="text-align: left;"><strong><font face="黑体" color=blue size = 5>glat</font></strong></td>
<td style="text-align: left;">南北向网格信息:[起始纬度,终止纬度,纬向间隔]</td>
</tr>
<tr>
<td style="text-align: left;"><strong>gtime</strong></td>
<td style="text-align: left;">时间网格信息:若gtime只包含1个元 素,其内容为datetime变量,或者常用字符形式时间,例如"2019123108"、"2019-12-31:08"或"19年12月31日08时"等方式都能兼容。若gtime包含三个元素,其内容为[起始时间,结束时间,时间间隔], 其中时间格式可以是datetime变量或者字符串形式,时间间隔为字符串,例如"12h"代表12小时,"30m"代表30分钟。</td>
</tr>
<tr>
<td style="text-align: left;"><strong>dtime_list</strong></td>
<td style="text-align: left;">时效列表,其元素dtime为整数</td>
</tr>
<tr>
<td style="text-align: left;"><strong>level_list</strong></td>
<td style="text-align: left;">层次名称列表</td>
</tr>
<tr>
<td style="text-align: left;"><strong>member_list</strong></td>
<td style="text-align: left;">成员名称列表</td>
</tr>
<tr>
<td style="text-align: left;"><font face="黑体" color=blue size=5>return</font></td>
<td style="text-align: left;">返回一个网格信息类的变量,其中会包含成员、层次、时间、时效、纬度、经度等六个维度的坐标信息</td>
</tr>
</tbody>
</table>
<p><strong>其初始化方式如以下示例</strong></p>
<pre><code class="language-python">grid0 = meb.grid([100,110,1],[22,20,-1]) #初始化一个网格,其中时间、时效、层次和成员信息都暂时使用缺省设置
print(grid0)</code></pre>
<pre><code>members:['data0']
levels:[0]
gtime:['20990101000000', '20990101000000', '1h']
dtimes:[0]
glon:[100, 110.0, 1]
glat:[22, 20.0, -1]</code></pre>
<pre><code class="language-python">grid0 = meb.grid([100,110,1],[22,20,-1],gtime=[&quot;2019013108&quot;,&quot;2019020108&quot;,&quot;24h&quot;],dtime_list = [24],level_list = [0],member_list = [&quot;GRAPES&quot;])
print(grid0)</code></pre>
<pre><code>members:['GRAPES']
levels:[0]
gtime:['20190131080000', '20190201080000', '24h']
dtimes:[24]
glon:[100, 110.0, 1]
glat:[22, 20.0, -1]</code></pre>
<p><strong><font face="黑体" color=black size = 5>网格数据类</font></strong>
格式为<a href="http://xarray.pydata.org/en/stable/data-structures.html">xarray.DataArray</a>的数据。本函数库提供了对该网格数据的一序列初始化、读写和转换函数,经过本函数库初始化、读取或转换生成的网格数据统一具备顺序为member,level,time,dtime,lat,lon 共6个维度的坐标,其中水平方向为等经纬度坐标。</p>
<h1>初始化网格数据</h1>
<p><strong><font face="黑体" color=blue size = 5>grid_data(grid,data=None)</font></strong><br />
根据网格信息初始化一个网格数据</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><font face="黑体" color=blue size = 5>grid</font></strong></td>
<td style="text-align: left;">网格信息类变量</td>
</tr>
<tr>
<td style="text-align: left;"><strong>data</strong></td>
<td style="text-align: left;">numpy数组,缺省时生成内容全为0的网格数据</td>
</tr>
<tr>
<td style="text-align: left;"><font face="黑体" color=blue size=5>return</font></td>
<td style="text-align: left;">xarray.DataArray格式数据,其中依次包含member,level,time,dtime,lat,lon共6个维度的信息。</td>
</tr>
</tbody>
</table>
<p><strong>调用示例</strong></p>
<pre><code class="language-python">grd = meb.grid_data(grid0) #根据网格信息生成网格数据,网格值都为0
print(grd)</code></pre>
<pre><code>&lt;xarray.DataArray 'data0' (member: 1, level: 1, time: 2, dtime: 1, lat: 3, lon: 11)&gt;
array([[[[[[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]],
[[[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]]]]])
Coordinates:
* member (member) &lt;U6 'GRAPES'
* level (level) int32 0
* time (time) datetime64[ns] 2019-01-31T08:00:00 2019-02-01T08:00:00
* dtime (dtime) int32 24
* lat (lat) int32 22 21 20
* lon (lon) int32 100 101 102 103 104 105 106 107 108 109 110</code></pre>
<pre><code class="language-python">x= np.arange(11)
y= np.arange(3)
xx,yy = np.meshgrid(x,y)
dat = np.array([xx,yy])
grd = meb.grid_data(grid0,dat) #根据网格信息和numpy数组生成网格数
print(grd)</code></pre>
<pre><code>&lt;xarray.DataArray 'data0' (member: 1, level: 1, time: 2, dtime: 1, lat: 3, lon: 11)&gt;
array([[[[[[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]],
[[[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]]]]]])
Coordinates:
* member (member) &lt;U6 'GRAPES'
* level (level) int32 0
* time (time) datetime64[ns] 2019-01-31T08:00:00 2019-02-01T08:00:00
* dtime (dtime) int32 24
* lat (lat) int32 22 21 20
* lon (lon) int32 100 101 102 103 104 105 106 107 108 109 110</code></pre>
<h1>重置网格数据</h1>
<p><strong><font face="黑体" color=blue size = 5>reset(grd)</font></strong><br />
将网格的经向坐标调整为由西向东递增,由南向北递增 </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><font face="黑体" color=blue size = 5>grd</font></strong></td>
<td style="text-align: left;">网格数据</td>
</tr>
<tr>
<td style="text-align: left;"><font face="黑体" color=blue size=5>return</font></td>
<td style="text-align: left;">None</td>
</tr>
</tbody>
</table>
<p><strong>调用示例</strong></p>
<pre><code class="language-python">meb.reset(grd)
print(grd) #重置后坐标及相应的数据都会相应调整</code></pre>
<pre><code>&lt;xarray.DataArray 'data0' (member: 1, level: 1, time: 2, dtime: 1, lat: 3, lon: 11)&gt;
array([[[[[[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]],
[[[ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]]]]])
Coordinates:
* member (member) &lt;U6 'GRAPES'
* level (level) int32 0
* time (time) datetime64[ns] 2019-01-31T08:00:00 2019-02-01T08:00:00
* dtime (dtime) int32 24
* lat (lat) int32 20 21 22
* lon (lon) int32 100 101 102 103 104 105 106 107 108 109 110</code></pre>
<h1>提取网格信息</h1>
<p><strong><font face="黑体" color=blue size = 5>get_grid_of_data(grd)</font></strong><br />
从网格数据中提取网格信息,以一个网格信息类变量来返回。 </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><font face="黑体" color=blue size = 5>grd</font></strong></td>
<td style="text-align: left;">网格数据</td>
</tr>
<tr>
<td style="text-align: left;"><font face="黑体" color=blue size=5>return</font></td>
<td style="text-align: left;">网格信息类变量</td>
</tr>
</tbody>
</table>
<p><strong>调用示例</strong></p>
<pre><code class="language-python">grid1 = meb.get_grid_of_data(grd)
print(grid1) #打印重置后的网格信息</code></pre>
<pre><code>members:['GRAPES']
levels:[0]
gtime:['20190131080000', '20190201080000', '24h']
dtimes:[24]
glon:[100, 110.0, 1]
glat:[20, 22.0, 1]</code></pre>
<h1>设置网格的坐标属性</h1>
<p><strong><font face="黑体" color=blue size = 5>set_griddata_coords(grd,name = None,gtime = None,dtime_list = None, level_list = None, member_list = None):</font></strong><br />
对网格的维度坐标属性进行设置 </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><font face="黑体" color=blue size = 5>grd</font></strong></td>
<td style="text-align: left;">网格数据</td>
</tr>
<tr>
<td style="text-align: left;"><strong>name</strong></td>
<td style="text-align: left;">数据内容名称,缺省时不做改变</td>
</tr>
<tr>
<td style="text-align: left;"><strong>level_list</strong></td>
<td style="text-align: left;">数据内容名称,缺省时不做改变</td>
</tr>
<tr>
<td style="text-align: left;"><strong>gtime</strong></td>
<td style="text-align: left;">时间坐标参数列表,它可以包括3个或1个元素。当grid_data的time维度size=1时,gtime只包含1个元素,其内容为datetime变量,或者常用字符形式时间,例如"2019123108"、"2019-12-31:08"或"19年12月31日08时"等方式都能兼容。如果grid_data的time维度size>1,则gtime包含三个元素其内容为,分别为[起始时间,结束时间,时间间隔], 其中时间格式可以是datetime变量或者字符串形式,时间间隔为字符串,例如"12h"代表12小时,"30m"代表30分钟。,缺省时不做改变</td>
</tr>
<tr>
<td style="text-align: left;"><strong>dtime_list</strong></td>
<td style="text-align: left;">时效坐标列表,其元素dtime为整数,若取值小于10000,则时效 = dtime小时,若取值大10000,则代表 时效 = (dtime - 10000)分钟,缺省时不做改变</td>
</tr>
<tr>
<td style="text-align: left;"><strong>member_list</strong></td>
<td style="text-align: left;">成员名称列表,缺省时不做改变</td>
</tr>
<tr>
<td style="text-align: left;"><font face="黑体" color=blue size=5>return</font></td>
<td style="text-align: left;">None</td>
</tr>
</tbody>
</table>
<p><strong>调用示例</strong></p>
<pre><code class="language-python">meb.set_griddata_coords(grd,name = &quot;Temperature&quot;,level_list = [0],gtime=[&quot;2019-01-31:08&quot;],dtime_list = [24],member_list = [&quot;GRAPES&quot;])
print(grd)</code></pre>
<pre><code>gtime对应的时间序列长度和grid_data的time维度的长度不一致
&lt;xarray.DataArray 'Temperature' (member: 1, level: 1, time: 2, dtime: 1, lat: 3, lon: 11)&gt;
array([[[[[[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]],
[[[ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]]]]])
Coordinates:
* member (member) &lt;U6 'GRAPES'
* level (level) int32 0
* time (time) datetime64[ns] 2019-01-31T08:00:00 2019-02-01T08:00:00
* dtime (dtime) int32 24
* lat (lat) int32 20 21 22
* lon (lon) int32 100 101 102 103 104 105 106 107 108 109 110</code></pre>
<pre><code class="language-python">time1 = datetime.datetime(2019,2,1,8,0)
meb.set_griddata_coords(grd,gtime=[time1])
print(grd)</code></pre>
<pre><code>gtime对应的时间序列长度和grid_data的time维度的长度不一致
&lt;xarray.DataArray 'Temperature' (member: 1, level: 1, time: 2, dtime: 1, lat: 3, lon: 11)&gt;
array([[[[[[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]],
[[[ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]]]]])
Coordinates:
* member (member) &lt;U6 'GRAPES'
* level (level) int32 0
* time (time) datetime64[ns] 2019-01-31T08:00:00 2019-02-01T08:00:00
* dtime (dtime) int32 24
* lat (lat) int32 20 21 22
* lon (lon) int32 100 101 102 103 104 105 106 107 108 109 110</code></pre>
<h1>将一般的xarray数据转换为grid_data</h1>
<p><strong><font face="黑体" color=blue size = 5>xarray_to_griddata(xr0,value_name = None,member_dim = None,level_dim = None,time_dim = None,dtime_dim = None,lat_dim = None,lon_dim = None):</font></strong><br />
对将一般的xarray数据转换成grid_data格式数据,缺省的维度会自动补齐 </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><font face="黑体" color=blue size = 5>xr0</font></strong></td>
<td style="text-align: left;"><a href="http://xarray.pydata.org/en/stable/data-structures.html">一般的xarray数据,可以是DataArray格式,也可以是DataSet格式</a></td>
</tr>
<tr>
<td style="text-align: left;"><strong>value_name</strong></td>
<td style="text-align: left;">当xr0是DataSet格式时,且包含多个非坐标变量时,可以用value_name指定提取某一个变量</td>
</tr>
<tr>
<td style="text-align: left;"><strong>member_dim</strong></td>
<td style="text-align: left;">指定xr0中某个变量代表member维度坐标</td>
</tr>
<tr>
<td style="text-align: left;"><strong>level_dim</strong></td>
<td style="text-align: left;">指定xr0中某个变量代表level维度坐标</td>
</tr>
<tr>
<td style="text-align: left;"><strong>time_dim</strong></td>
<td style="text-align: left;">指定xr0中某个变量代表time维度坐标</td>
</tr>
<tr>
<td style="text-align: left;"><strong>dtime_dim</strong></td>
<td style="text-align: left;">指定xr0中某个变量代表dtime维度坐标</td>
</tr>
<tr>
<td style="text-align: left;"><strong>lat_dim</strong></td>
<td style="text-align: left;">指定xr0中某个变量代表latitude维度坐标</td>
</tr>
<tr>
<td style="text-align: left;"><strong>lon_dim</strong></td>
<td style="text-align: left;">指定xr0中某个变量代表longitude维度坐标</td>
</tr>
<tr>
<td style="text-align: left;"><font face="黑体" color=blue size=5>return</font></td>
<td style="text-align: left;">grid_data格式的网格数据</td>
</tr>
</tbody>
</table>
<p><strong>调用示例</strong></p>
<pre><code class="language-python">#构建测试数据
data0 = np.random.rand(5,3)
data1 = np.ones((5,3))
x = np.arange(110,115,1)
y= np.arange(30,33,1)
da0 = xr.DataArray(data0, coords=[x,y], dims=['lon','lat'])
da1 = xr.DataArray(data1, coords=[x,y], dims=['x','y'])
print(da0) #da0是一个DataArray格式数据
print(da1) #da1是一个DataArray格式数据</code></pre>
<pre><code>&lt;xarray.DataArray (lon: 5, lat: 3)&gt;
array([[0.692929, 0.256168, 0.060266],
[0.50581 , 0.611408, 0.024281],
[0.494839, 0.036597, 0.546739],
[0.967274, 0.657783, 0.061574],
[0.058702, 0.711008, 0.681518]])
Coordinates:
* lon (lon) int32 110 111 112 113 114
* lat (lat) int32 30 31 32
&lt;xarray.DataArray (x: 5, y: 3)&gt;
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
Coordinates:
* x (x) int32 110 111 112 113 114
* y (y) int32 30 31 32</code></pre>
<pre><code class="language-python">ds0 = xr.Dataset({&quot;xr0&quot;:da0,&quot;xr1&quot;:da1})
print(ds0) #ds0是一个DataSet格式数据</code></pre>
<pre><code>&lt;xarray.Dataset&gt;
Dimensions: (lat: 3, lon: 5, x: 5, y: 3)
Coordinates:
* lon (lon) int32 110 111 112 113 114
* lat (lat) int32 30 31 32
* x (x) int32 110 111 112 113 114
* y (y) int32 30 31 32
Data variables:
xr0 (lon, lat) float64 0.6929 0.2562 0.06027 ... 0.0587 0.711 0.6815
xr1 (x, y) float64 1.0 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0 1.0</code></pre>
<pre><code class="language-python">grd =meb.xarray_to_griddata(da0)
print(grd) #对于da0里面的维度坐标名称为lon,lat,程序能够自动识别</code></pre>
<pre><code>&lt;xarray.DataArray 'data0' (member: 1, level: 1, time: 1, dtime: 1, lat: 3, lon: 5)&gt;
array([[[[[[0.692929, 0.50581 , 0.494839, 0.967274, 0.058702],
[0.256168, 0.611408, 0.036597, 0.657783, 0.711008],
[0.060266, 0.024281, 0.546739, 0.061574, 0.681518]]]]]])
Coordinates:
* member (member) int32 0
* level (level) int32 0
* time (time) int32 0
* dtime (dtime) int32 0
* lat (lat) int32 30 31 32
* lon (lon) int32 110 111 112 113 114</code></pre>
<pre><code class="language-python">grd =meb.xarray_to_griddata(da1,lat_dim = &quot;y&quot;,lon_dim = &quot;x&quot;)
print(grd) #在da1中需要指定哪个坐标变量代表经度,哪个代表纬度</code></pre>
<pre><code>&lt;xarray.DataArray 'data0' (member: 1, level: 1, time: 1, dtime: 1, lat: 3, lon: 5)&gt;
array([[[[[[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]]]]]])
Coordinates:
* member (member) int32 0
* level (level) int32 0
* time (time) int32 0
* dtime (dtime) int32 0
* lat (lat) int32 30 31 32
* lon (lon) int32 110 111 112 113 114</code></pre>
<pre><code class="language-python">grd =meb.xarray_to_griddata(ds0)
print(grd) #在ds0中有多个非坐标量,xr0和xr1,在不指定value_name的情况下,默认提取第一个变量即xr0的内容</code></pre>
<pre><code>&lt;xarray.DataArray 'xr0' (member: 1, level: 1, time: 1, dtime: 1, lat: 3, lon: 5)&gt;
array([[[[[[0.692929, 0.50581 , 0.494839, 0.967274, 0.058702],
[0.256168, 0.611408, 0.036597, 0.657783, 0.711008],
[0.060266, 0.024281, 0.546739, 0.061574, 0.681518]]]]]])
Coordinates:
* member (member) int32 0
* level (level) int32 0
* time (time) int32 0
* dtime (dtime) int32 0
* lat (lat) int32 30 31 32
* lon (lon) int32 110 111 112 113 114</code></pre>
<pre><code class="language-python">grd =meb.xarray_to_griddata(ds0,value_name = &quot;xr1&quot;,lon_dim = &quot;x&quot;,lat_dim = &quot;y&quot;)
print(grd) #在ds0中有多个非坐标量,xr0和xr1,根据value_name指定提取了xr1变量的内容</code></pre>
<pre><code>&lt;xarray.DataArray 'xr1' (member: 1, level: 1, time: 1, dtime: 1, lat: 3, lon: 5)&gt;
array([[[[[[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]]]]]])
Coordinates:
* member (member) int32 0
* level (level) int32 0
* time (time) int32 0
* dtime (dtime) int32 0
* lat (lat) int32 30 31 32
* lon (lon) int32 110 111 112 113 114</code></pre>
<pre><code class="language-python"></code></pre>