本帖最后由 2184 于 2024-9-20 17:59 编辑
1. 空间插值实例与代码
数据准备:
案例数据是根据土壤剖面推导的黄土高原气温、降水(下载地址:https://doi.org/10.6084/m9.figshare.25263637.v1)。
- import pandas as pd
- import numpy as np
- df = pd.read_excel("/下载/25263637/Paleoclimate data of the 180 modern soils.xlsx",sheet_name='Data')
复制代码
读取结果:
Sample Longitude (°) Latitude (°) Precipitation (mm) Temperature (°C) cfd (m3/kg) Hematite (g/kg)
0 MS-1 108.355767 37.709567 356.361 8.333 1.918159 1.912016
1 MS-2 107.626517 37.418967 331.914 8.286 1.329787 2.068267
2 MS-3 104.430650 35.711850 365.322 6.643 1.756757 2.861642
3 MS-4 104.765900 35.665383 380.359 5.960 4.011461 2.591716
4 MS-5 105.158983 35.570183 397.854 5.653 2.631579 2.836020
... ... ... ... ... ... ... ...
175 MS-176 105.260210 35.441560 401.010 5.666 4.048583 2.809483
176 MS-177 105.019330 35.715930 387.716 5.856 2.200825 2.888728
177 MS-178 104.951970 35.944250 356.024 6.589 5.738881 3.541073
178 MS-179 103.620770 35.724660 368.705 7.873 0.257069 3.444593
179 MS-180 106.704390 37.571310 295.204 8.147 0.721154 1.745166
180 rows × 7 columns
1.1 Kriging
路径:数据读入→数据预处理→变差函数计算→变差函数拟合→插值→等值线绘制
(0)相关概念
(I)平稳假设
区域化变量的随机函数F(x)在各阶矩相对恒定,一般只要求一阶矩(数学期望)、二阶矩(方差)平稳,即在随机场中不同点的随机变量产生的概率分布相等。
(II)无偏估计。克里金权重之和等于1。
(III)变差函数(variogram或semi-variogram)
含义:空间随机场上两个点形成的随机变量,随机变量方差之大作为函数。两点(i, j)距离h越小、方差越小。数学含义为:方差与两点的协方差(cov(i,j))相减,等价于两点(x=i, j)在F(x)上两个函数值之差的方差的二分之一。
类型(代码中的variogram_model):1.球状模型(spherical)。2.指数模型(exponential)。3.高斯模型(gaussian)。
重要参数:①块金(nugget):随机场粗糙程度。②基台值(sill):空间随机场起伏程度。③变程(range):空间相关性存在范围。pykrige还有nlags:对于半方差模型的平均箱数(bins),默认为6。
(1)普通克里金(Ordinary Kriging)
方程组考虑条件极值问题,采用拉格朗日算法。数学期望未知,只要满足二阶平稳假设。
利用pykrige工具的函数OrdinaryKriging()插值黄土高原气温点。可以选择半变异函数(variogram_model)类型。调整对于半方差模型的平均箱数(nlags,默认为6):是将成对的地点归为一个距离类别的大小。
- # Ordinary Kriging
- from pykrige.ok import OrdinaryKriging
- # 建立插值网格,分辨率0.25°×0.25°(即~25km)。oklon为经度,oklat为纬度
- oklon = np.arange(df['Longitude (°)'].min(),df['Longitude (°)'].max(),0.25)
- oklat = np.arange(df['Latitude (°)'].min(),df['Latitude (°)'].max(),0.25)
- # 普通克里金插值:当 半变异函数(variogram_model)选择 spherical
- OK = OrdinaryKriging(df['Longitude (°)'],df['Latitude (°)'],df['Temperature (°C)'],
- variogram_model="spherical",verbose=False,enable_plotting=False,coordinates_type='geographic',nlags=6)
- temp1, ss1 = OK.execute('grid',oklon,oklat)
复制代码
插值得到的气温面数据temp1和原始散点数据df绘图:
- # 绘图
- import matplotlib.pyplot as plt
- import cartopy.crs as ccrs # 坐标系
- import cartopy.feature as cfeat
- extents = [103, 120, 34, 41] # 经纬度范围
- crs = ccrs.PlateCarree() # 坐标系
- fig = plt.figure() # 可调整,例如figsize=(10,8),dpi=500
- ax1 = fig.add_subplot(111, projection=crs) # 创建子图,111是把画板分成1行1列的第1张图
- x_extent = [105, 110, 115, 120]
- y_extent = [30, 35, 40, 45]
- ax1.set_title('Temperature of Loess Plateau (Ordinary Kriging)',loc='center')
- ax1.set_xticks(x_extent, crs=ccrs.PlateCarree()) #添加边框的经纬度标记
- ax1.set_yticks(y_extent, crs=ccrs.PlateCarree())
- ax1.set_extent(extents, crs)
- # 绘制海洋、河流、海岸线,需连接网络!!!!!
- ax1.add_feature(cfeat.OCEAN.with_scale('110m'), linewidth=0.5, zorder=1)
- ax1.coastlines()
- # 绘制插值结果(imshow)和站点实际值(scatter,散点颜色、边框、坐标系、与其他图的位置)
- s1 = ax1.imshow(temp1,origin='lower', cmap='RdYlGn_r', transform=crs,extent=[df['Longitude (°)'].min(), df['Longitude (°)'].max(), df['Latitude (°)'].min(), df['Latitude (°)'].max()])
- ax1.scatter(df['Longitude (°)'], df['Latitude (°)'], c=df['Temperature (°C)'], cmap='RdYlGn_r', edgecolors='black', transform=ccrs.PlateCarree(), zorder=2)
- cb1 = fig.colorbar(s1,ax=ax1,orientation='horizontal') # 水平色带图例
- cb1.set_label('°C')
- plt.show()
复制代码
绘图结果:
(2)泛克里金(universal kriging)
用于解决非平稳随机场的方法,在数学期望和协方差不同(协方差不平稳)时使用,可看成在局部范围内平稳。比较不同nlags:
- from pykrige.uk import UniversalKriging
- import numpy as np
- # 建立插值网格,分辨率0.25°×0.25°(即~25km)
- uklon = np.arange(df['Longitude (°)'].min(),df['Longitude (°)'].max(),0.25)
- uklat = np.arange(df['Latitude (°)'].min(),df['Latitude (°)'].max(),0.25)
- # 克里金插值:当半变异函数(variogram_model)选择 spherical时
- uk = UniversalKriging(df['Longitude (°)'],df['Latitude (°)'],df['Temperature (°C)'],
- variogram_model='spherical',verbose=False,enable_plotting=False)# 默认nlags=6
- tempuk, ssuk = uk.execute('grid',uklon,uklat)
- uk1 = UniversalKriging(df['Longitude (°)'],df['Latitude (°)'],df['Temperature (°C)'],
- variogram_model='spherical',verbose=False,enable_plotting=False,nlags=1)
- tempuk1, ssuk1 = uk1.execute('grid',uklon,uklat)
复制代码
绘图代码同普通克里金,结果如图:
(3)协同克里金(Co-Kriging)
使用条件是,主变量的信息不足,而次要变量的信息充分(例如主变量为温度,气象台站点稀少,用更多辅助变量(高程)协助插值);主次变量存在一定相关性(例如温度和高程);估值时在搜索半径内至少存在一个主变量采样点。
(4)回归克里金(Regression kriging)
- # RK
- # 具体请参考https://geostat-framework.readthedocs.io/projects/pykrige/en/latest/generated/pykrige.rk.RegressionKriging.html
- from pykrige.rk import RegressionKriging
- RegressionKriging()
复制代码
|