[Refactoring] N-dimenstional Kriging
See original GitHub issueJust a few thoughts about possible code refactoring in PyKrige.
Currently PyKrige has separate code that implements 2D and 3D kriging (e.g. in ok.py
and ok3d.py
), this result in code duplication and makes code maintenance and adding new features more difficult (they need to be added to every single file). Besides the 1D Kriging is not implemented, and it might have been nice to have some 1D examples as they are easier to visualize.
In addition, PR #24 adds a scikit-learn API to PyKrige on top of the existing UniversalKrigging
and OrdinaryKrigging
methods.
A possible solution to remove the current code duplication, would be to refactor the UniversalKrigging
and OrdinaryKrigging
to work in N-dimensions. The simplest way of doing it would be to use something along the lines of the scikit-learn API which will also remove the need for an additional wrapper for that. The general API could be something like,
class OrdinaryKrigging(pykrige.compat.BaseEstimator):
def __init__(self, <kriging options>):
[..]
def fit(X, y):
""" Where X is an array [n_samples, n_dimensions] and y is an array [n_samples]"""
[...]
def predict(X):
""" Where X is an array [n_samples, n_dimensions]
The equivalent of the current execute(style="points", ...)
"""
[...]
The case of execute(style="masked", ...)
could be done by supporting masked arrays for predict(X)
, while the case execute(style="grid", ...)
can be done with a helper function,
def points2grid(**points):
""" points: a list of arrays e.g [zpts, ypts, xpts] """
grids = np.meshgrid(*points, indexing='ij')
return np.concatenate([grid.flatten()[:, None] for grid in grids])
which is mostly what is done internally by execute
at present.
This would break backward compatibility though, so a major version change would be needed (PyKrige v2).
Update: the refactoring could follow the steps below,
- in
core.py
mergeadjust_for_anisotropy
andadjust_for_anisotropy_3d
into a single private function_adjust_for_anisotropy(X, center, scaling, angle)
where X is a[n_samples, n_dim]
array, and all the other are list of floats and, it returns theX_modified
array. (PR #33 ) - in
core.py
merge theinitialize_variogram_model
andinitialize_variogram_model_3d
into a single private function (PR #47 )_initialize_variogram_model(X, y, variogram_model, variogram_model_parameters, variogram_function, nlags, weight)
- in
core.py
merge thekrige
andkrige_3d
into a single private function_krige(X, y, coords, variogram_function, variogram_model_parameters)
(PR #51 ) - in
core.py
similarly mergefind_statistics*
(PR #51) - create a new ND kriging class for ordinary Kriging that follows the scikit-learn compatible api. We need to decide on a name
OrdinaryKriging
would be great but it’s already taken). MaybeOrdinaryNDKriging
? - rewrite the internals of
OrdinaryKriging
andOrdinaryKriging3D
to useOrdinaryNDKriging
internally. - rewrite specific tests for
OrdinaryNDKriging
and add deprecation warnings onOrdinaryKriging
,OrdinaryKriging3D
- do the same thing for other kriging methods
- after a few versions remove the old style kriging interface.
What do you think?
Issue Analytics
- State:
- Created 7 years ago
- Reactions:2
- Comments:12 (9 by maintainers)
@rth Your list looks good to me. I also reviewed your most recent PR and cross checked both the functions that you have manged to pull together into one.
@rth Thank you for putting this list together. I will go through your list in detail tonight. A bit under the pump today.