def alpha_nse(obs: DataArray, sim: DataArray) -> float: # verify inputs _validate_inputs(obs, sim) # get time series with only valid observations obs, sim = _mask_valid(obs, sim) return float(sim.std() / obs.std())
def kge(obs: DataArray, sim: DataArray, weights: List[float] = [1., 1., 1.]) -> float: r"""Calculate the Kling-Gupta Efficieny [#]_ .. math:: \text{KGE} = 1 - \sqrt{[ s_r (r - 1)]^2 + [s_\alpha ( \alpha - 1)]^2 + [s_\beta(\beta_{\text{KGE}} - 1)]^2}, where :math:`r` is the correlation coefficient, :math:`\alpha` the :math:`\alpha`-NSE decomposition, :math:`\beta_{\text{KGE}}` the fraction of the means and :math:`s_r, s_\alpha, s_\beta` the corresponding weights (here the three float values in the `weights` parameter). Parameters ---------- obs : DataArray Observed time series. sim : DataArray Simulated time series. weights : List[float] Weighting factors of the 3 KGE parts, by default each part has a weight of 1. Returns ------- float Kling-Gupta Efficiency References ---------- .. [#] Gupta, H. V., Kling, H., Yilmaz, K. K., & Martinez, G. F. (2009). Decomposition of the mean squared error and NSE performance criteria: Implications for improving hydrological modelling. Journal of hydrology, 377(1-2), 80-91. """ if len(weights) != 3: raise ValueError("Weights of the KGE must be a list of three values") # verify inputs _validate_inputs(obs, sim) # get time series with only valid observations obs, sim = _mask_valid(obs, sim) if len(obs) < 2: return np.nan r, _ = stats.pearsonr(obs.values, sim.values) alpha = sim.std() / obs.std() beta = sim.mean() / obs.mean() value = (weights[0] * (r - 1)**2 + weights[1] * (alpha - 1)**2 + weights[2] * (beta - 1)**2) return 1 - np.sqrt(float(value))
def kge(obs: DataArray, sim: DataArray, weights: list = [1, 1, 1]) -> float: if len(weights) != 3: raise ValueError("Weights of the KGE must be a list of three values") # verify inputs _validate_inputs(obs, sim) # get time series with only valid observations obs, sim = _mask_valid(obs, sim) r, _ = stats.pearsonr(obs.values, sim.values) alpha = sim.std() / obs.std() beta = sim.mean() / obs.mean() value = (weights[0] * (r - 1)**2 + weights[1] * (alpha - 1)**2 + weights[2] * (beta - 1)**2) return 1 - np.sqrt(float(value))
def alpha_nse(obs: DataArray, sim: DataArray) -> float: r"""Calculate the alpha NSE decomposition [#]_ The alpha NSE decomposition is the fraction of the standard deviations of simulations and observations. .. math:: \alpha = \frac{\sigma_s}{\sigma_o}, where :math:`\sigma_s` is the standard deviation of the simulations (here, `sim`) and :math:`\sigma_o` is the standard deviation of the observations (here, `obs`). Parameters ---------- obs : DataArray Observed time series. sim : DataArray Simulated time series. Returns ------- float Alpha NSE decomposition. References ---------- .. [#] Gupta, H. V., Kling, H., Yilmaz, K. K., & Martinez, G. F. (2009). Decomposition of the mean squared error and NSE performance criteria: Implications for improving hydrological modelling. Journal of hydrology, 377(1-2), 80-91. """ # verify inputs _validate_inputs(obs, sim) # get time series with only valid observations obs, sim = _mask_valid(obs, sim) return float(sim.std() / obs.std())