Contents¶
PyKrige¶
Kriging Toolkit for Python
The code supports 2D and 3D ordinary and universal kriging. Standard variogram models (linear, power, spherical, gaussian, exponential) are built in, but custom variogram models can also be used. The 2D universal kriging code currently supports regional-linear, point-logarithmic, and external drift terms, while the 3D universal kriging code supports a regional-linear drift term in all three spatial dimensions. Both universal kriging classes also support generic ‘specified’ and ‘functional’ drift capabilities. With the ‘specified’ drift capability, the user may manually specify the values of the drift(s) at each data point and all grid points. With the ‘functional’ drift capability, the user may provide callable function(s) of the spatial coordinates that define the drift(s). The package includes a module that contains functions that should be useful in working with ASCII grid files (*.asc).
See the documentation at http://pykrige.readthedocs.io/en/stable/ for more details.
Installation¶
PyKrige requires Python 2.7 or 3.5+ as well as numpy, scipy and matplotlib. It can be installed from PyPi with,
pip install pykrige
scikit-learn is an optional dependency needed for parameter tuning and regression kriging.
If you use conda, PyKrige can be installed from the conda-forge channel with,
conda install -c conda-forge pykrige
Ordinary Kriging Example¶
First we will create a 2D dataset together with the associated x, y grids,
import numpy as np
import pykrige.kriging_tools as kt
data = np.array([[0.3, 1.2, 0.47],
[1.9, 0.6, 0.56],
[1.1, 3.2, 0.74],
[3.3, 4.4, 1.47],
[4.7, 3.8, 1.74]])
gridx = np.arange(0.0, 5.5, 0.5)
gridy = np.arange(0.0, 5.5, 0.5)
# Create the ordinary kriging object. Required inputs are the X-coordinates of
# the data points, the Y-coordinates of the data points, and the Z-values of the
# data points. If no variogram model is specified, defaults to a linear variogram
# model. If no variogram model parameters are specified, then the code automatically
# calculates the parameters by fitting the variogram model to the binned
# experimental semivariogram. The verbose kwarg controls code talk-back, and
# the enable_plotting kwarg controls the display of the semivariogram.
OK = OrdinaryKriging(data[:, 0], data[:, 1], data[:, 2], variogram_model='linear',
verbose=False, enable_plotting=False)
# Creates the kriged grid and the variance grid. Allows for kriging on a rectangular
# grid of points, on a masked rectangular grid of points, or with arbitrary points.
# (See OrdinaryKriging.__doc__ for more information.)
z, ss = OK.execute('grid', gridx, gridy)
# Writes the kriged grid to an ASCII grid file.
kt.write_asc_grid(gridx, gridy, z, filename="output.asc")
Universal Kriging Example¶
from pykrige.uk import UniversalKriging
import numpy as np
data = np.array([[0.3, 1.2, 0.47],
[1.9, 0.6, 0.56],
[1.1, 3.2, 0.74],
[3.3, 4.4, 1.47],
[4.7, 3.8, 1.74]])
gridx = np.arange(0.0, 5.5, 0.5)
gridy = np.arange(0.0, 5.5, 0.5)
# Create the ordinary kriging object. Required inputs are the X-coordinates of
# the data points, the Y-coordinates of the data points, and the Z-values of the
# data points. Variogram is handled as in the ordinary kriging case.
# drift_terms is a list of the drift terms to include; currently supported terms
# are 'regional_linear', 'point_log', and 'external_Z'. Refer to
# UniversalKriging.__doc__ for more information.
UK = UniversalKriging(data[:, 0], data[:, 1], data[:, 2], variogram_model='linear',
drift_terms=['regional_linear'])
# Creates the kriged grid and the variance grid. Allows for kriging on a rectangular
# grid of points, on a masked rectangular grid of points, or with arbitrary points.
# (See UniversalKriging.__doc__ for more information.)
z, ss = UK.execute('grid', gridx, gridy)
Three-Dimensional Kriging Example¶
from pykrige.ok3d import OrdinaryKriging3D
from pykrige.uk3d import UniversalKriging3D
import numpy as np
data = np.array([[0.1, 0.1, 0.3, 0.9],
[0.2, 0.1, 0.4, 0.8],
[0.1, 0.3, 0.1, 0.9],
[0.5, 0.4, 0.4, 0.5],
[0.3, 0.3, 0.2, 0.7]])
gridx = np.arange(0.0, 0.6, 0.05)
gridy = np.arange(0.0, 0.6, 0.01)
gridz = np.arange(0.0, 0.6, 0.1)
# Create the 3D ordinary kriging object and solves for the three-dimension kriged
# volume and variance. Refer to OrdinaryKriging3D.__doc__ for more information.
ok3d = OrdinaryKriging3D(data[:, 0], data[:, 1], data[:, 2], data[:, 3],
variogram_model='linear')
k3d, ss3d = ok3d.execute('grid', gridx, gridy, gridz)
# Create the 3D universal kriging object and solves for the three-dimension kriged
# volume and variance. Refer to UniversalKriging3D.__doc__ for more information.
uk3d = UniversalKriging3D(data[:, 0], data[:, 1], data[:, 2], data[:, 3],
variogram_model='linear', drift_terms=['regional_linear'])
k3d, ss3d = uk3d.execute('grid', gridx, gridy, gridz)
# To use the generic 'specified' drift term, the user must provide the drift values
# at each data point and at every grid point. The following example is equivalent to
# using a linear drift in all three spatial dimensions. Refer to
# UniversalKriging3D.__doc__ for more information.
zg, yg, xg = np.meshgrid(gridz, gridy, gridx, indexing='ij')
uk3d = UniversalKriging3D(data[:, 0], data[:, 1], data[:, 2], data[:, 3],
variogram_model='linear', drift_terms=['specified'],
specified_drift=[data[:, 0], data[:, 1]])
k3d, ss3d = uk3d.execute('grid', gridx, gridy, gridz, specified_drift_arrays=[xg, yg, zg])
# To use the generic 'functional' drift term, the user must provide a callable
# function that takes only the spatial dimensions as arguments. The following example
# is equivalent to using a linear drift only in the x-direction. Refer to
# UniversalKriging3D.__doc__ for more information.
func = lambda x, y, z: x
uk3d = UniversalKriging3D(data[:, 0], data[:, 1], data[:, 2], data[:, 3],
variogram_model='linear', drift_terms=['functional'],
functional_drift=[func])
k3d, ss3d = uk3d.execute('grid', gridx, gridy, gridz)
# Note that the use of the 'specified' and 'functional' generic drift capabilities is
# essentially identical in the two-dimensional universal kriging class (except for a
# difference in the number of spatial coordinates for the passed drift functions).
# See UniversalKriging.__doc__ for more information.
Kriging Parameters Tuning¶
A scikit-learn compatible API for parameter tuning by cross-validation is exposed in sklearn.model_selection.GridSearchCV. See the Krige CV example for a more practical illustration.
Regression Kriging¶
Regression kriging can be performed
with pykrige.rk.RegressionKriging.
This class takes as parameters a scikit-learn regression model, and details of either either
the OrdinaryKriging
or the UniversalKriging
class, and performs a correction steps on the ML regression prediction.
A demonstration of the regression kriging is provided in the corresponding example.
License¶
PyKrige uses the BSD 3-Clause License.
Variogram Models¶
PyKrige internally supports the six variogram models listed below. Additionally, the code supports user-defined variogram models via the ‘custom’ variogram model keyword argument.
- Gaussian Model
- Exponential Model
- Spherical Model
- Linear Model
Where s is the slope and n is the nugget.
- Power Model
Where s is the scaling factor, e is the exponent (between 0 and 2), and n is the nugget term.
- Hole-Effect Model
Variables are defined as:
\(d\) = distance values at which to calculate the variogram
\(p\) = partial sill (psill = sill - nugget)
\(r\) = range
\(n\) = nugget
\(s\) = scaling factor or slope
\(e\) = exponent for power model
For stationary variogram models (gaussian, exponential, spherical, and hole-effect models), the partial sill is defined as the difference between the full sill and the nugget term. The sill represents the asymptotic maximum spatial variance at longest lags (distances). The range represents the distance at which the spatial variance has reached ~95% of the sill variance. The nugget effectively takes up ‘noise’ in measurements. It represents the random deviations from an overall smooth spatial data trend. (The name nugget is an allusion to kriging’s mathematical origin in gold exploration; the nugget effect is intended to take into account the possibility that when sampling you randomly hit a pocket gold that is anomalously richer than the surrounding area.)
For nonstationary models (linear and power models, with unbounded spatial variances), the nugget has the same meaning. The exponent for the power-law model should be between 0 and 2 [1].
A few important notes:
The PyKrige user interface by default takes the full sill. This default behavior can be changed with a keyword flag, so that the user can supply the partial sill instead. The code internally uses the partial sill (psill = sill - nugget) rather than the full sill, as it’s safer to perform automatic variogram estimation using the partial sill.
The exact definitions of the variogram models here may differ from those used elsewhere. Keep that in mind when switching from another kriging code over to PyKrige.
According to [1], the hole-effect variogram model is only correct for the 1D case. It’s implemented here for completeness and should be used cautiously.
References¶
[1] | P.K. Kitanidis, Introduction to Geostatistcs: Applications in Hydrogeology, (Cambridge University Press, 1997) 272 p. |
API Reference¶
Krigging algorithms¶
pykrige.ok.OrdinaryKriging (x, y, z[, …]) |
Convenience class for easy access to 2D Ordinary Kriging. |
pykrige.uk.UniversalKriging (x, y, z[, …]) |
Provides greater control over 2D kriging by utilizing drift terms. |
pykrige.ok3d.OrdinaryKriging3D (x, y, z, val) |
Three-dimensional ordinary kriging |
pykrige.uk3d.UniversalKriging3D (x, y, z, val) |
Three-dimensional universal kriging |
pykrige.rk.RegressionKriging ([…]) |
This is an implementation of Regression-Kriging as described here: |
Wrappers¶
pykrige.rk.Krige ([method, variogram_model, …]) |
A scikit-learn wrapper class for Ordinary and Universal Kriging. |
Tools¶
pykrige.kriging_tools.write_asc_grid (x, y, z) |
Writes gridded data to ASCII grid file (*.asc). |
pykrige.kriging_tools.read_asc_grid (filename) |
Reads ASCII grid file (*.asc). |
Examples¶
Krige CV¶
Searching for optimal kriging parameters with cross validation
Out:
Fitting 3 folds for each of 8 candidates, totalling 24 fits
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
best_score R² = -0.030
best_params = {'method': 'ordinary', 'variogram_model': 'power'}
CV results::
- mean_test_score : [-0.03194734 -0.03036039 -0.0730884 -0.12390364 -0.03437615 -0.04016295
-0.08348872 -0.12087894]
- mean_train_score : [ 1. 1. 1. 1. 1. 1. 1. 1.]
- param_method : ['ordinary' 'ordinary' 'ordinary' 'ordinary' 'universal' 'universal'
'universal' 'universal']
- param_variogram_model : ['linear' 'power' 'gaussian' 'spherical' 'linear' 'power' 'gaussian'
'spherical']
Fitting 3 folds for each of 8 candidates, totalling 24 fits
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
n_closest_points will be ignored for UniversalKriging
best_score R² = 0.001
best_params = {'method': 'universal3d', 'variogram_model': 'gaussian'}
CV results::
- mean_test_score : [-0.15076042 -0.15101485 -0.15294586 -0.15537616 -0.03021721 -0.0499446
0.00147667 0.0005714 ]
- mean_train_score : [ 1. 1. 1. 1. 1. 1. 1. 1.]
- param_method : ['ordinary3d' 'ordinary3d' 'ordinary3d' 'ordinary3d' 'universal3d'
'universal3d' 'universal3d' 'universal3d']
- param_variogram_model : ['linear' 'power' 'gaussian' 'spherical' 'linear' 'power' 'gaussian'
'spherical']
import numpy as np
from pykrige.rk import Krige
from pykrige.compat import GridSearchCV
# 2D Kring param opt
param_dict = {"method": ["ordinary", "universal"],
"variogram_model": ["linear", "power", "gaussian", "spherical"],
# "nlags": [4, 6, 8],
# "weight": [True, False]
}
estimator = GridSearchCV(Krige(), param_dict, verbose=True)
# dummy data
X = np.random.randint(0, 400, size=(100, 2)).astype(float)
y = 5 * np.random.rand(100)
# run the gridsearch
estimator.fit(X=X, y=y)
if hasattr(estimator, 'best_score_'):
print('best_score R² = {:.3f}'.format(estimator.best_score_))
print('best_params = ', estimator.best_params_)
print('\nCV results::')
if hasattr(estimator, 'cv_results_'):
for key in ['mean_test_score', 'mean_train_score',
'param_method', 'param_variogram_model']:
print(' - {} : {}'.format(key, estimator.cv_results_[key]))
# 3D Kring param opt
param_dict3d = {"method": ["ordinary3d", "universal3d"],
"variogram_model": ["linear", "power", "gaussian", "spherical"],
# "nlags": [4, 6, 8],
# "weight": [True, False]
}
estimator = GridSearchCV(Krige(), param_dict3d, verbose=True)
# dummy data
X3 = np.random.randint(0, 400, size=(100, 3)).astype(float)
y = 5 * np.random.rand(100)
# run the gridsearch
estimator.fit(X=X3, y=y)
if hasattr(estimator, 'best_score_'):
print('best_score R² = {:.3f}'.format(estimator.best_score_))
print('best_params = ', estimator.best_params_)
print('\nCV results::')
if hasattr(estimator, 'cv_results_'):
for key in ['mean_test_score', 'mean_train_score',
'param_method', 'param_variogram_model']:
print(' - {} : {}'.format(key, estimator.cv_results_[key]))
Total running time of the script: ( 0 minutes 2.881 seconds)
Regression kriging¶
An example of regression kriging
Out:
========================================
regression model: SVR
Finished learning regression model
Finished kriging residuals
Regression Score: -0.034053855457
RK score: 0.66195576665
========================================
regression model: RandomForestRegressor
Finished learning regression model
Finished kriging residuals
Regression Score: 0.703244702246
RK score: 0.744378796543
========================================
regression model: LinearRegression
Finished learning regression model
Finished kriging residuals
Regression Score: 0.527796839838
RK score: 0.604908933617
from sklearn.svm import SVR
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LinearRegression
from sklearn.datasets import fetch_california_housing
from pykrige.rk import RegressionKriging
from pykrige.compat import train_test_split
svr_model = SVR(C=0.1)
rf_model = RandomForestRegressor(n_estimators=100)
lr_model = LinearRegression(normalize=True, copy_X=True, fit_intercept=False)
models = [svr_model, rf_model, lr_model]
# take the first 5000 as Kriging is memory intensive
housing = fetch_california_housing()
p = housing['data'][:5000, :-2]
x = housing['data'][:5000, -2:]
target = housing['target'][:5000]
p_train, p_test, x_train, x_test, target_train, target_test \
= train_test_split(p, x, target, test_size=0.3, random_state=42)
for m in models:
print('=' * 40)
print('regression model:', m.__class__.__name__)
m_rk = RegressionKriging(regression_model=m, n_closest_points=10)
m_rk.fit(p_train, x_train, target_train)
print('Regression Score: ', m_rk.regression_model.score(p_test, target_test))
print('RK score: ', m_rk.score(p_test, x_test, target_test))
##====================================OUTPUT==================================
# ========================================
# regression model: <class 'sklearn.svm.classes.SVR'>
# Finished learning regression model
# Finished kriging residuals
# Regression Score: -0.034053855457
# RK score: 0.66195576665
# ========================================
# regression model: <class 'sklearn.ensemble.forest.RandomForestRegressor'>
# Finished learning regression model
# Finished kriging residuals
# Regression Score: 0.699771164651
# RK score: 0.737574040386
# ========================================
# regression model: <class 'sklearn.linear_model.base.LinearRegression'>
# Finished learning regression model
# Finished kriging residuals
# Regression Score: 0.527796839838
# RK score: 0.604908933617
Total running time of the script: ( 0 minutes 13.677 seconds)
1D Kriging¶
An example of 1D kriging with PyKrige

import os
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
# Data taken from https://blog.dominodatalab.com/fitting-gaussian-process-models-python/
X, y = np.array([[-5.01, 1.06], [-4.90, 0.92], [-4.82, 0.35], [-4.69, 0.49], [-4.56, 0.52],
[-4.52, 0.12], [-4.39, 0.47], [-4.32,-0.19], [-4.19, 0.08], [-4.11,-0.19],
[-4.00,-0.03], [-3.89,-0.03], [-3.78,-0.05], [-3.67, 0.10], [-3.59, 0.44],
[-3.50, 0.66], [-3.39,-0.12], [-3.28, 0.45], [-3.20, 0.14], [-3.07,-0.28],
[-3.01,-0.46], [-2.90,-0.32], [-2.77,-1.58], [-2.69,-1.44], [-2.60,-1.51],
[-2.49,-1.50], [-2.41,-2.04], [-2.28,-1.57], [-2.19,-1.25], [-2.10,-1.50],
[-2.00,-1.42], [-1.91,-1.10], [-1.80,-0.58], [-1.67,-1.08], [-1.61,-0.79],
[-1.50,-1.00], [-1.37,-0.04], [-1.30,-0.54], [-1.19,-0.15], [-1.06,-0.18],
[-0.98,-0.25], [-0.87,-1.20], [-0.78,-0.49], [-0.68,-0.83], [-0.57,-0.15],
[-0.50, 0.00], [-0.38,-1.10], [-0.29,-0.32], [-0.18,-0.60], [-0.09,-0.49],
[0.03 ,-0.50], [0.09 ,-0.02], [0.20 ,-0.47], [0.31 ,-0.11], [0.41 ,-0.28],
[0.53 , 0.40], [0.61 , 0.11], [0.70 , 0.32], [0.94 , 0.42], [1.02 , 0.57],
[1.13 , 0.82], [1.24 , 1.18], [1.30 , 0.86], [1.43 , 1.11], [1.50 , 0.74],
[1.63 , 0.75], [1.74 , 1.15], [1.80 , 0.76], [1.93 , 0.68], [2.03 , 0.03],
[2.12 , 0.31], [2.23 ,-0.14], [2.31 ,-0.88], [2.40 ,-1.25], [2.50 ,-1.62],
[2.63 ,-1.37], [2.72 ,-0.99], [2.80 ,-1.92], [2.83 ,-1.94], [2.91 ,-1.32],
[3.00 ,-1.69], [3.13 ,-1.84], [3.21 ,-2.05], [3.30 ,-1.69], [3.41 ,-0.53],
[3.52 ,-0.55], [3.63 ,-0.92], [3.72 ,-0.76], [3.80 ,-0.41], [3.91 , 0.12],
[4.04 , 0.25], [4.13 , 0.16], [4.24 , 0.26], [4.32 , 0.62], [4.44 , 1.69],
[4.52 , 1.11], [4.65 , 0.36], [4.74 , 0.79], [4.84 , 0.87], [4.93 , 1.01],
[5.02 , 0.55]]).T
from pykrige import OrdinaryKriging
X_pred = np.linspace(-6, 6, 200)
# pykrige doesn't support 1D data for now, only 2D or 3D
# adapting the 1D input to 2D
uk = OrdinaryKriging(X, np.zeros(X.shape), y, variogram_model='gaussian',)
y_pred, y_std = uk.execute('grid', X_pred, np.array([0.]))
y_pred = np.squeeze(y_pred)
y_std = np.squeeze(y_std)
fig, ax = plt.subplots(1, 1, figsize=(10, 4))
ax.scatter(X, y, s=40, label='Input data')
ax.plot(X_pred, y_pred, label='Predicted values')
ax.fill_between(X_pred, y_pred - 3*y_std, y_pred + 3*y_std, alpha=0.3, label='Confidence interval')
ax.legend(loc=9)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_xlim(-6, 6)
ax.set_ylim(-2.8, 3.5)
if 'CI' not in os.environ:
# skip in continous integration
plt.show()
Total running time of the script: ( 0 minutes 0.089 seconds)
Geometric example¶
A small example script showing the usage of the ‘geographic’ coordinates type for ordinary kriging on a sphere.
Out:
Original data:
Longitude: [122 166 92 138 86 122 136]
Latitude: [-46 -36 -25 -73 -25 50 -29]
z: [ 2.75 3.36 2.24 3.07 3.37 5.25 2.82]
Krige at 60° latitude:
======================
Longitude: [ 0. 60. 120. 180. 240. 300. 360.]
Value: [ 5.32 5.14 5.3 5.18 5.35 5.61 5.32]
Sigma²: [ 2.2 1.32 0.41 1.22 2.11 2.47 2.2 ]
Ignoring curvature:
=====================
Value: [ 4.55 4.72 5.25 4.82 4.61 4.53 4.48]
Sigma²: [ 3.79 2. 0.39 1.85 3.54 5.46 7.53]
from pykrige.ok import OrdinaryKriging
import numpy as np
# Make this example reproducible:
np.random.seed(89239413)
# Generate random data following a uniform spatial distribution
# of nodes and a uniform distribution of values in the interval
# [2.0, 5.5]:
N = 7
lon = 360.0*np.random.random(N)
lat = 180.0/np.pi*np.arcsin(2*np.random.random(N)-1)
z = 3.5*np.random.rand(N) + 2.0
# Generate a regular grid with 60° longitude and 30° latitude steps:
grid_lon = np.linspace(0.0, 360.0, 7)
grid_lat = np.linspace(-90.0, 90.0, 7)
# Create ordinary kriging object:
OK = OrdinaryKriging(lon, lat, z, variogram_model='linear', verbose=False,
enable_plotting=False, coordinates_type='geographic')
# Execute on grid:
z1, ss1 = OK.execute('grid', grid_lon, grid_lat)
# Create ordinary kriging object ignoring curvature:
OK = OrdinaryKriging(lon, lat, z, variogram_model='linear', verbose=False,
enable_plotting=False)
# Execute on grid:
z2, ss2 = OK.execute('grid', grid_lon, grid_lat)
# Print data at equator (last longitude index will show periodicity):
print("Original data:")
print("Longitude:",lon.astype(int))
print("Latitude: ",lat.astype(int))
print("z: ",np.array_str(z, precision=2))
print("\nKrige at 60° latitude:\n======================")
print("Longitude:",grid_lon)
print("Value: ",np.array_str(z1[5,:], precision=2))
print("Sigma²: ",np.array_str(ss1[5,:], precision=2))
print("\nIgnoring curvature:\n=====================")
print("Value: ",np.array_str(z2[5,:], precision=2))
print("Sigma²: ",np.array_str(ss2[5,:], precision=2))
##====================================OUTPUT==================================
# >>> Original data:
# >>> Longitude: [122 166 92 138 86 122 136]
# >>> Latitude: [-46 -36 -25 -73 -25 50 -29]
# >>> z: [ 2.75 3.36 2.24 3.07 3.37 5.25 2.82]
# >>>
# >>> Krige at 60° latitude:
# >>> ======================
# >>> Longitude: [ 0. 60. 120. 180. 240. 300. 360.]
# >>> Value: [ 5.32 5.14 5.3 5.18 5.35 5.61 5.32]
# >>> Sigma²: [ 2.19 1.31 0.41 1.22 2.1 2.46 2.19]
# >>>
# >>> Ignoring curvature:
# >>> =====================
# >>> Value: [ 4.55 4.72 5.25 4.82 4.61 4.53 4.48]
# >>> Sigma²: [ 3.77 1.99 0.39 1.84 3.52 5.43 7.5 ]
#
# We can see that the data point at longitude 122, latitude 50 correctly
# dominates the kriged results, since it is the closest node in spherical
# distance metric, as longitude differences scale with cos(latitude).
# When kriging using longitude / latitude linearly, the value for grid points
# with longitude values further away as longitude is now incorrectly
# weighted equally as latitude.
Total running time of the script: ( 0 minutes 0.040 seconds)