Evaluator

hydroeval.evaluator(obj_fn, simulations, evaluation, axis=0, transform=None, epsilon=None)

Evaluate the goodness of fit between one time series of simulated streamflow stored in a 1D array (or several time series of equal length stored in a 2D array) and one time series of the corresponding observed streamflow for the same period stored in a 1D array. Missing values can be set as numpy.nan for paiwise deletion to be performed.

Parameters
obj_fn: hydroeval objective function

The objective function to use to evaluate the goodness of fit between the simulations series and the evaluation series.

Parameter example:

obj_fn=hydroeval.nse

Parameter example:

obj_fn=hydroeval.kge
simulations: array-like object

The array of simulated streamflow values to be compared against the observation using the obj_fn. Note, the array can be one or two dimensional. If it is 2D, the time dimension must be the one specified through axis.

evaluation: array-like object

The array of observed streamflow values to be compared against the simulations using the obj_fn. Note, the array can be one or two dimensional. If it is 2D, the dimension specified through axis must be of size 1. Moreover, the length of the evaluation series must match the length of simulations series ― missing values must be set as numpy.nan so that pairwise deletion in both simulations and evaluation series can be performed prior the calculation of the obj_fn.

axis: int, optional

The axis along which the simulations and/or evaluation time dimension is, if any is a 2D array. If not provided, set to default value 0.

transform: str, optional

The transformation to apply to both the simulations and evaluation streamflow values Q prior the evaluation of the goodness of fit with the obj_fn. If not provided, set to default value None (i.e. no transformation). The supported transform arguments are listed in the table below.

transformations

details

'inv'

The reciprocal function f(Q) = 1/Q is applied.

'sqrt'

The square root function f(Q) = √Q is applied.

'log'

The natural logarithm function f(Q) = ln(Q) is applied.

epsilon: float, optional

The value of the small constant ε to add to both the simulations and evaluation streamflow values Q prior the evaluation of the goodness of fit with the obj_fn when the transform is the reciprocal function or the natural logarithm since neither are defined for 0. If not provided, set to default value equal to one hundredth of the mean of the evaluation streamflow series, as recommended by Pushpalatha et al. (2012).

Examples

>>> import hydroeval as he
>>> print(
...     he.evaluator(
...         he.nse,
...         [5.3, 4.2, 5.7, 2.3],
...         [4.7, 4.3, 5.5, 2.7]
...    )
... )
[0.86298077]
>>> print(
...     he.evaluator(
...         he.kge,
...         [5.3, 4.2, 5.7, 2.3],
...         [4.7, 4.3, 5.5, 2.7]
...     )
... )
[[0.7066232 ]
 [0.98213905]
 [1.2923127 ]
 [1.01744186]]

Computations on multiple simulation series at once are possible.

>>> print(
...     he.evaluator(
...         he.kge,
...         [[5.3, 4.6],
...          [4.2, 4.2],
...          [5.7, 5.3],
...          [2.3, 2.8]],
...         [4.7, 4.3, 5.5, 2.7]
...     )
... )
[[0.7066232  0.8929297 ]
 [0.98213905 0.99985551]
 [1.2923127  0.89436   ]
 [1.01744186 0.98255814]]
>>> print(
...     he.evaluator(
...         he.kge,
...         [[5.3, 4.2, 5.7, 2.3],
...          [4.6, 4.2, 5.3, 2.8]],
...         [4.7, 4.3, 5.5, 2.7],
...         axis=1
...     )
... )
[[0.7066232  0.98213905 1.2923127  1.01744186]
 [0.8929297  0.99985551 0.89436    0.98255814]]

In case of missing observations (flagged as NaN), hydroeval performs pairwise deletion.

>>> import numpy as np
>>> print(
...     he.evaluator(
...         he.nse,
...         [5.3, 4.2, 5.7, 2.3],
...         [4.7, 4.3, np.nan, 2.7]
...     )
... )
[0.76339286]
>>> print(
...     he.evaluator(
...         he.nse,
...         [5.3, 4.2, 2.3],
...         [4.7, 4.3, 2.7]
...     )
... )
[0.76339286]

Pre-computation transformations on data are possible with parameter transform.

>>> print(
...     he.evaluator(
...         he.nse,
...         [5.3, 4.2, 5.7, 2.3],
...         [4.7, 4.3, 5.5, 2.7],
...         transform='sqrt'
...     )
... )
[0.86356266]

When using the reciprocal or logarithm transform function, a default epsilon is added to all flows to avoid zero flows. epsilon is customisable.

>>> print(
...     he.evaluator(
...         he.kge,
...         [5.3, 4.2, 5.7, 0.0],
...         [4.7, 4.3, 5.5, 0.1],
...         transform='inv'
...     )
... )
[[-2.78380731]
 [ 0.99999157]
 [ 3.82066207]
 [ 3.52211483]]
>>> print(
...     he.evaluator(
...         he.kge,
...         [5.3, 4.2, 5.7, 0.0],
...         [4.7, 4.3, 5.5, 0.1],
...         transform='inv',
...         epsilon=0.073
...     )
... )
[[-0.88255825]
 [ 0.99999145]
 [ 2.42185928]
 [ 2.23383214]]