Code source de pyspc.model.sauquet

#!/usr/bin/python3
# -*- coding: utf-8 -*-
########################################################################
#
# This file is part of python module <pyspc>.
# Copyright (C) 2013-2021  R. Marty
#   (renaud.marty@developpement-durable.gouv.fr)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see COPYING.txt).
# If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
"""
Régime hydro-météorologique par Sauquet
"""
import numpy as np
import pandas as pnd
import pyspc.core.exception as _exception

REGIMES = pnd.DataFrame({
    ('0', 'nivo_glaciaire'): [-0.96, -1.08, -0.96, -0.60, 0.36, 1.44,
                              1.68, 1.32, 0.48, -0.24, -0.60, -0.84],
    ('1', 'nival'): [-0.84, -0.98, -0.84, -0.14, 1.41, 2.25,
                     0.98, 0.14, -0.28, -0.42, -0.56, -0.70],
    ('2', 'nival_transition'): [-0.85, -0.85, -0.64, 0, 1.71, 2.14,
                                0.85, 0, -0.64, -0.64, -0.43, -0.64],
    ('3', 'nivo_pluvial'): [-0.69, -0.92, 0.46, 1.61, 2.07, 0.23,
                            -0.46, -0.92, -1.15, -0.69, 0, 0.46],
    ('4', 'pluvial_1'): [1.11, 1.18, 1.25, 1.11, 0.34, -0.37,
                         -0.80, -1.36, -1.36, -1.01, -0.51, 0.41],
    ('5', 'pluvial_2'): [1.36, 1.17, 0.76, 0.73, -0.07, -0.76,
                         -1.25, -1.55, -1.14, -0.56, 0.40, 0.92],
    ('6', 'pluvial_3'): [1.07, 1.40, 0.92, 1.07, 0.52, -0.43,
                         -1.15, -1.41, -1.24, -0.93, -0.22, 0.42],
    ('7', 'pluvial_4'): [1.56, 0.99, 0.76, 0.23, -0.45, -0.87,
                         -1.17, -1.32, -1.02, -0.45, 0.33, 1.14],
    ('8', 'pluvial_5'): [1.94, 1.28, 0.56, 0.30, -0.38, -0.86,
                         -1.05, -1.15, -0.97, -0.68, 0.06, 0.96],
    ('9', 'pluvial_6'): [1.44, 1.40, 0.67, 0.71, 0.05, -0.78,
                         -1.16, -1.36, -1.16, -0.78, 0.11, 0.86],
    ('10', 'pluvial_7'): [1.17, 0.18, -0.03, 0.33, 0.08, -0.93,
                          -1.43, -1.50, -0.99, 0.52, 1.59, 1],
    ('11', 'pluvial_8'): [0.84, 0.43, 0.52, 1.22, 1.13, -0.33,
                          -1.39, -1.74, -1.30, -0.48, 0.55, 0.55]},
    index=range(1, 13)
)


[docs] def compute_distance(df): """ Définir la similarité du régime hydrologique avec les références Sauquet. Parameters ---------- df : pandas.DataFrame Valeurs mensuelles Returns ------- norm : pandas.DataFrame Valeurs mensuelles normalisées regimes : pandas.DataFrame Identifiants des colonnes de df, des régimes et critère de similarité See Also -------- pyspc.model.sauquet.REGIMES Examples -------- >>> import pyspc.model.sauquet as _sauquet >>> df = pnd.DataFrame( ... {'K2163110': [1.430, 1.540, 1.700, 1.670, 1.320, 0.829, ... 0.380, 0.241, 0.324, 0.613, 1.140, 1.440]}, ... index=range(12)) >>> df K2163110 1 1.430 2 1.540 3 1.700 4 1.670 5 1.320 6 0.829 7 0.380 8 0.241 9 0.324 10 0.613 11 1.140 12 1.440 >>> norm, regimes = _sauquet.compute_distance(df) >>> norm K2163110 1 0.690228 2 0.891221 3 1.183574 4 1.128758 5 0.489235 6 -0.407924 7 -1.228341 8 -1.482323 9 -1.330664 10 -0.802601 11 0.160338 12 0.708500 >>> regimes source id_regime lbl_regime distance 0 K2163110 0 nivo_glaciaire 6.364468 1 K2163110 1 nival 5.542722 2 K2163110 2 nival_transition 5.212776 3 K2163110 3 nivo_pluvial 3.144169 4 K2163110 4 pluvial_1 1.033849 5 K2163110 5 pluvial_2 1.226321 6 K2163110 6 pluvial_3 0.860899 7 K2163110 7 pluvial_4 1.820628 8 K2163110 8 pluvial_5 2.027160 9 K2163110 9 pluvial_6 1.290835 10 K2163110 10 pluvial_7 2.705927 11 K2163110 11 pluvial_8 1.214482 """ # ===================================================================== # 0- CONTROLES # ===================================================================== _exception.raise_valueerror( not isinstance(df, pnd.DataFrame), "Les valeurs ne sont pas fournies sous forme de DataFrame") months = list(range(1, 13)) _exception.raise_valueerror( len(df.index) != len(months) or not all([x in df.index for x in months]), "Les valeurs sont incomplètes") # ===================================================================== # 1- MISE EN FORME DES DONNEES : NORMALISATION # ===================================================================== norm = (df - df.mean()) / df.std() # ===================================================================== # 2- CALCUL DES CRITERES DE SIMILARITE PAR REGIME SAUQUET # ===================================================================== regimes = [] for c in norm.columns: for kr, vr in REGIMES.items(): d = np.sqrt(np.sum(np.power( norm[c].to_frame().values.squeeze() - vr.values, 2))) regimes.append((c, kr[0], kr[1], d)) regimes = pnd.DataFrame.from_records( regimes, columns=['source', 'id_regime', 'lbl_regime', 'distance']) regimes['id_regime'] = regimes['id_regime'].astype(np.int64) return norm, regimes