Code source de pyspc.io.lamedo.reader

#!/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/>.
#
########################################################################
"""Bibliothèque pyspc du projet pyspc - IO - LAMEDO - read."""
from datetime import timedelta as td
import numpy as np
import pandas as pnd

from pyspc.core.keyseries import str2tuple, tuple2str
from pyspc.core.parameter import Parameter
from pyspc.core.serie import Serie
from pyspc.core.series import Series
import pyspc.core.exception as _exception
from pyspc.convention.lamedo import (
    BDAPBP_SCENS, BDIMAGE_RATIOS, BDIMAGE_PREFIX)
from pyspc.data.lamedo import BdApbp, BdImage

PROVIDER = 'BdImage'


[docs] def read_BdImage(filename=None, ratio_image=1, ratio_stats=1, warning=True): """ Créer une instance Series à partir de données BdImage. Parameters ---------- filename : str Nom du fichier d'observations de Météo-France ratio_image : float Ratio minimal requis pour les images ratio_stats : float Ratio minimal requis pour les statistiques warning : bool Imprimer les erreurs ? Returns ------- series : pyspc.core.series.Series Collection de séries de données Examples -------- >>> from pyspc.io.lamedo import read_BdImage Cas d'observations statistiques sur une zone >>> f = 'data'/data/lamedo/getObsStatsByZones_antilope-j1-rr_000100.xml' >>> series = read_BdImage(filename=f) >>> series ************************************* ********** SERIES ******************* ************************************* * NOM DE LA COLLECTION = BdImage * TYPE DE COLLECTION = obs * NOMBRE DE SERIES = 14 * ---------------------------------- * SERIE #1 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,cvar * ---------------------------------- * SERIE #2 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,etyp * ---------------------------------- * SERIE #3 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,max * ---------------------------------- * SERIE #4 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,med * ---------------------------------- * SERIE #5 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,min * ---------------------------------- * SERIE #6 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,moy * ---------------------------------- * SERIE #7 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q10 * ---------------------------------- * SERIE #8 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q20 * ---------------------------------- * SERIE #9 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q30 * ---------------------------------- * SERIE #10 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q40 * ---------------------------------- * SERIE #11 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q60 * ---------------------------------- * SERIE #12 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q70 * ---------------------------------- * SERIE #13 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q80 * ---------------------------------- * SERIE #14 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q90 ************************************* Cas d'observations statistiques sur une zone avec application de ratios >>> f = 'data'/data/lamedo/getObsStatsByZones_antilope-j1-rr_000100.xml' >>> series = read_BdImage(filename=f, ratio_image=0.8, ratio_stats=0.8) Avertissement : le ratio 'image' est inférieur au seuil de tolérance (0.80 > 12/24=0.5) pour l'image detype=antilope, soustype=j1 et date=2021-05-09 06:00:00 Avertissement : le ratio 'stats' est inférieur au seuil de tolérance (0.80 > 10/19=0.5263157894736842) pour la statistique deloc=LO8060 >>> series ************************************* ********** SERIES ******************* ************************************* * NOM DE LA COLLECTION = BdImage * TYPE DE COLLECTION = obs * NOMBRE DE SERIES = 14 * ---------------------------------- * SERIE #1 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,cvar * ---------------------------------- * SERIE #2 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,etyp * ---------------------------------- * SERIE #3 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,max * ---------------------------------- * SERIE #4 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,med * ---------------------------------- * SERIE #5 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,min * ---------------------------------- * SERIE #6 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,moy * ---------------------------------- * SERIE #7 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q10 * ---------------------------------- * SERIE #8 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q20 * ---------------------------------- * SERIE #9 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q30 * ---------------------------------- * SERIE #10 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q40 * ---------------------------------- * SERIE #11 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q60 * ---------------------------------- * SERIE #12 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q70 * ---------------------------------- * SERIE #13 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q80 * ---------------------------------- * SERIE #14 * - CODE = LO8060 * - VARNAME = PH * - META = antilope,j1,rr,q90 ************************************* Cas d'observations 'pixel' sur une bbox >>> f = 'data'/data/lamedo/getObsValuesByBBox_antilope-j1-rr_010000.xml' >>> series = read_BdImage(filename=f) >>> series ************************************* ********** SERIES ******************* ************************************* * NOM DE LA COLLECTION = BdImage * TYPE DE COLLECTION = obs * NOMBRE DE SERIES = 4 * ---------------------------------- * SERIE #1 * - CODE = 793500.0,6412500.0 * - VARNAME = PJ * - META = antilope,j1,rr,val * ---------------------------------- * SERIE #2 * - CODE = 793500.0,6413500.0 * - VARNAME = PJ * - META = antilope,j1,rr,val * ---------------------------------- * SERIE #3 * - CODE = 794500.0,6412500.0 * - VARNAME = PJ * - META = antilope,j1,rr,val * ---------------------------------- * SERIE #4 * - CODE = 794500.0,6413500.0 * - VARNAME = PJ * - META = antilope,j1,rr,val ************************************* Cas d'observations 'pixel' sur une bbox - Température >>> f = 'data'/data/lamedo/getObsValuesByBBox_sim-t-t.xml' >>> series = read_BdImage(filename=f) >>> series ************************************* ********** SERIES ******************* ************************************* * NOM DE LA COLLECTION = BdImage * TYPE DE COLLECTION = obs * NOMBRE DE SERIES = 6 * ---------------------------------- * SERIE #1 * - CODE = 779000.0,6404000.0 * - VARNAME = TI * - META = sim,t,t,val * ---------------------------------- * SERIE #2 * - CODE = 779000.0,6412000.0 * - VARNAME = TI * - META = sim,t,t,val * ---------------------------------- * SERIE #3 * - CODE = 779000.0,6420000.0 * - VARNAME = TI * - META = sim,t,t,val * ---------------------------------- * SERIE #4 * - CODE = 787000.0,6404000.0 * - VARNAME = TI * - META = sim,t,t,val * ---------------------------------- * SERIE #5 * - CODE = 787000.0,6412000.0 * - VARNAME = TI * - META = sim,t,t,val * ---------------------------------- * SERIE #6 * - CODE = 787000.0,6420000.0 * - VARNAME = TI * - META = sim,t,t,val ************************************* Cas de prévisions statistiques sur une zone >>> f = 'data'/data/lamedo/getPrevByNetworkStatsByZones_pprod-rr-total.xml' >>> series = read_BdImage(filename=f) >>> series ************************************* ********** SERIES ******************* ************************************* * NOM DE LA COLLECTION = BdImage * TYPE DE COLLECTION = fcst * NOMBRE DE SERIES = 1 * ---------------------------------- * SERIE #1 * - CODE = LO850 * - VARNAME = PH * - META = 2025-09-21 00:00:00+00:00, pprod, rr,total, moy ************************************* Cas de prévisions 'pixel' sur une bbox >>> f = 'data'/data/lamedo/getPrevByNetworkValuesByBBox_pprod-rr-total.xml' >>> series = read_BdImage(filename=f) >>> series ************************************* ********** SERIES ******************* ************************************* * NOM DE LA COLLECTION = BdImage * TYPE DE COLLECTION = fcst * NOMBRE DE SERIES = 4 * ---------------------------------- * SERIE #1 * - CODE = 793500.0,6412500.0 * - VARNAME = PH * - META = 2025-09-21 00:00:00+00:00, pprod, rr,total, val * ---------------------------------- * SERIE #2 * - CODE = 793500.0,6413500.0 * - VARNAME = PH * - META = 2025-09-21 00:00:00+00:00, pprod, rr,total, val * ---------------------------------- * SERIE #3 * - CODE = 794500.0,6412500.0 * - VARNAME = PH * - META = 2025-09-21 00:00:00+00:00, pprod, rr,total, val * ---------------------------------- * SERIE #4 * - CODE = 794500.0,6413500.0 * - VARNAME = PH * - META = 2025-09-21 00:00:00+00:00, pprod, rr,total, val ************************************* """ # ------------------------------------------------------------------------- # 0- Contrôles # ------------------------------------------------------------------------- _exception.check_str(filename) _exception.check_numeric(ratio_image) _exception.check_numeric(ratio_stats) _exception.check_bool(warning) provider = 'BdImage' # ------------------------------------------------------------------------- # 1- Lecture # ------------------------------------------------------------------------- # Création du lecteur reader = BdImage(filename=filename) # Lecture des données try: content = reader.read() except Exception: _exception.Warning( None, f"Formattage XML incorrect pour le fichier {filename}") return None # ------------------------------------------------------------------------- # 2- Contrôles du contenu XML # ------------------------------------------------------------------------- _exception.raise_valueerror( content.report.status != 0, "Le fichier XML de BdImage est incorrect : statut != 0") # ------------------------------------------------------------------------- # 3- Informations sur la requête # ------------------------------------------------------------------------- requestname = content.report.request['request'] # ------------------------------------------------------------------------- # 4- Traitement du XML et transformation en Series # ------------------------------------------------------------------------- if requestname.startswith('getObs'): return _convert_bdimage_obs( content=content, provider=provider, ratio_image=ratio_image, ratio_stats=ratio_stats, warning=warning) if requestname.startswith('getPrev'): return _convert_bdimage_prv( content=content, provider=provider, ratio_image=ratio_image, ratio_stats=ratio_stats, warning=warning) raise NotImplementedError( "Le traitement de la requête {} n'est pas implémenté")
def _convert_bdimage_obs(content=None, provider=None, ratio_image=None, ratio_stats=None, warning=True): """Convertir des données OBS de BdImage en pandas.DataFrame.""" # ------------------------------------------------------------------------- # 0- Initialisation de la collection # ------------------------------------------------------------------------- series = Series(datatype='obs', name='BdImage') # ------------------------------------------------------------------------- # 1- Images d'observation # ------------------------------------------------------------------------- dfs = [] for image in content.observations: df = __convert_bdimage_image( image, ratio_image=ratio_image, ratio_stats=ratio_stats) if df is None: continue dfs.append(df) try: df = pnd.concat(dfs, ignore_index=True) except ValueError: # Aucune série extraite return None # ------------------------------------------------------------------------- # 2- Transformation du DataFrame # ------------------------------------------------------------------------- df = df.set_index(keys=['LOC', 'FAMILY', 'KIND', 'BAND', 'DEPTH', 'RUNTIME', 'VALIDTIME']) df = df.unstack( level=['LOC', 'FAMILY', 'KIND', 'BAND', 'DEPTH', 'RUNTIME']) df = df.sort_index(axis=0) df = df.sort_index(axis=1) # ------------------------------------------------------------------------- # 3- Création des séries # ------------------------------------------------------------------------- for c in df.columns: img = '_'.join(c[2:5]) df[c] = df[c] * BDIMAGE_RATIOS[img][0] dfc = df[c].to_frame() try: target = c[5].to_pytimedelta() param = Parameter.find( prefix=BDIMAGE_PREFIX[img], timedelta=target if target != td(seconds=0) else None) except KeyError: if warning: _exception.Warning( None, f"La grandeur de la série '{c}' est inconnue. " "Elle est ignorée") continue else: varname = param.spc_varname key = (c[1], varname, '_'.join([img, c[0]]).replace('_', ',')) # Si journalier: retirer heure et soustraire 1 jour # BdImage: date = fin cumul # pyspc: date = jour du cumul if param.timestep == td(days=1): dfc.index = dfc.index.normalize() - param.timestep serie = Serie(dfc, code=key[0], varname=varname, provider=provider, warning=warning) series.add(serie, meta=key[2]) return series def __convert_bdimage_image(image, ratio_image=1, ratio_stats=1, isobs=True): """Extraire les informations Image du fichier XML BdImage.""" _exception.check_bool(isobs) _exception.check_numeric(ratio_image) _exception.check_numeric(ratio_stats) # ------------------------------------------------------------------------- # 0- Information sur l'image # ------------------------------------------------------------------------- family = image.specie.family kind = image.specie.kind depth = image.depth # image.specie.depth : pas de temps nominal de l'img validtime = image.date if isobs: runtime = None else: runtime = image.network if image.ratio.value < ratio_image: _exception.Warning( None, "le ratio 'image' est inférieur au seuil de tolérance " f"({ratio_image:.2f} > " f"{image.ratio.numerator:d}/{image.ratio.denominator:d}=" f"{image.ratio.value:.2f}) pour l'image de " f"type={family}, soustype={kind} et date={validtime}" ) return None # ------------------------------------------------------------------------- # 1- Bandes de l'image # ------------------------------------------------------------------------- dfs = [] for band in image.bands: df = __convert_bdimage_band(band, ratio_stats=ratio_stats) if df is None: continue df['FAMILY'] = family df['KIND'] = kind df['DEPTH'] = depth df['VALIDTIME'] = validtime df['RUNTIME'] = runtime dfs.append(df) if dfs: return pnd.concat(dfs, ignore_index=True) return None def __convert_bdimage_band(band, ratio_stats=1): """Extraire les informations Bande du fichier XML BdImage.""" dfs = [] # ------------------------------------------------------------------------- # 0- Information sur la bande # ------------------------------------------------------------------------- name = band.name # ------------------------------------------------------------------------- # 1- Statistiques # ------------------------------------------------------------------------- if band.stats: for stat in band.stats: df = __convert_bdimage_stats(stat, ratio_stats=ratio_stats) if df is None: continue df['BAND'] = name dfs.append(df.reset_index()) if dfs: return pnd.concat(dfs, ignore_index=True) return None # ------------------------------------------------------------------------- # 2- Valeurs # ------------------------------------------------------------------------- if band.samples: for sample in band.samples: df = __convert_bdimage_samples(sample) if df is None: continue df['BAND'] = name dfs.append(df.reset_index()) if dfs: return pnd.concat(dfs, ignore_index=True) return None return None def __convert_bdimage_samples(sample): """Extraire les informations Values du fichier XML BdImage.""" # ------------------------------------------------------------------------- # 1- Valeurs # ------------------------------------------------------------------------- df = pnd.DataFrame( sample.samples, index=[f"{xy[0]},{xy[1]}" for xy in sample.pixels]) df.index.name = 'LOC' df.columns = ['val'] return df def __convert_bdimage_stats(stat, ratio_stats=1): """Extraire les informations Stats du fichier XML BdImage.""" # ------------------------------------------------------------------------- # 0- Information sur la statistique # ------------------------------------------------------------------------- loc = stat.zone if stat.stat.ratio.value < ratio_stats: _exception.Warning( None, f"le ratio 'stats' est inférieur au seuil de tolérance " f"({ratio_stats:.2f} > " f"{stat.stat.ratio.numerator:d}/{stat.stat.ratio.denominator:d}" f"={stat.stat.ratio.denominator:.2f}) pour la " f"statistique de {loc=}" ) return None # ------------------------------------------------------------------------- # 1- Statistiques # ------------------------------------------------------------------------- df = pnd.DataFrame(stat.stat, index=[loc]) df.index.name = 'LOC' df = df.replace([np.inf, -np.inf], np.nan) return df def _convert_bdimage_prv(content=None, provider=None, ratio_image=None, ratio_stats=None, warning=True): """Convertir des données PREV de BdImage en pandas.DataFrame.""" # ------------------------------------------------------------------------- # 0- Initialisation de la collection # ------------------------------------------------------------------------- series = Series(datatype='fcst', name='BdImage') # ------------------------------------------------------------------------- # 1- Images de prévisions # ------------------------------------------------------------------------- dfs = [] for prev in content.previsions: for image in prev.images: df = __convert_bdimage_image( image, ratio_image=ratio_image, ratio_stats=ratio_stats, isobs=False) if df is None: continue dfs.append(df) try: df = pnd.concat(dfs, ignore_index=True) except ValueError: # Aucune série extraite return None # ------------------------------------------------------------------------- # 2- Transformation du DataFrame # ------------------------------------------------------------------------- df = df.set_index(keys=['LOC', 'FAMILY', 'KIND', 'BAND', 'DEPTH', 'RUNTIME', 'VALIDTIME']) df = df.unstack( level=['LOC', 'FAMILY', 'KIND', 'BAND', 'DEPTH', 'RUNTIME']) df = df.sort_index(axis=0) df = df.sort_index(axis=1) # ------------------------------------------------------------------------- # 3- Création des séries # ------------------------------------------------------------------------- for c in df.columns: img = '_'.join(c[2:5]) df[c] = df[c] * BDIMAGE_RATIOS[img][0] try: target = c[5].to_pytimedelta() param = Parameter.find( prefix=BDIMAGE_PREFIX[img], timedelta=target if target != td(seconds=0) else None) except KeyError: if warning: _exception.Warning( None, f"La grandeur de la série '{c}' est inconnue. " "Elle est ignorée") continue else: varname = param.spc_varname key = (c[1], varname, (c[6].to_pydatetime(), c[2], c[3] + ',' + c[4], c[0])) keystr = str2tuple(tuple2str(key), forceobs=True) serie = Serie(df[c].to_frame(), code=keystr[0], varname=varname, provider=provider, warning=warning) series.add(serie, code=c[1], meta=key[2]) return series
[docs] def read_BdApbp(filename=None, zones=None, warning=True): """ Créer une instance Series à partir de prévisions BdApbp. Parameters ---------- filename : str Nom du fichier prévisions BdApbp zones : list Liste des identifiants des zones à conserver. Par défaut, toutes les zones sont retenues warning : bool Imprimer les erreurs ? Returns ------- series : pyspc.core.series.Series Collection de séries de données Examples -------- >>> from pyspc.io.lamedo import read_BdApbp Cas d'un fichier au format 'short' >>> f = 'data/data/lamedo/bp_short.json' >>> series = read_BdApbp(filename=f) >>> series ************************************* ********** SERIES ******************* ************************************* * NOM DE LA COLLECTION = BdApbp * TYPE DE COLLECTION = fcst * NOMBRE DE SERIES = 8 * ---------------------------------- * SERIE #1 * - CODE = 41003 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, MoyInf * ---------------------------------- * SERIE #2 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, MoyInf * ---------------------------------- * SERIE #3 * - CODE = 41003 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, MoySup * ---------------------------------- * SERIE #4 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, MoySup * ---------------------------------- * SERIE #5 * - CODE = 41003 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, LocInf * ---------------------------------- * SERIE #6 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, LocInf * ---------------------------------- * SERIE #7 * - CODE = 41003 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, LocSup * ---------------------------------- * SERIE #8 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, LocSup ************************************* Cas d'un fichier au format 'short' avec sélection de zones >>> f = 'data/data/lamedo/bp_short.json' >>> series = read_BdApbp(filename=f, zones=['41005']) >>> series ************************************* ********** SERIES ******************* ************************************* * NOM DE LA COLLECTION = BdApbp * TYPE DE COLLECTION = fcst * NOMBRE DE SERIES = 4 * ---------------------------------- * SERIE #1 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, MoyInf * ---------------------------------- * SERIE #2 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, MoySup * ---------------------------------- * SERIE #3 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, LocInf * ---------------------------------- * SERIE #4 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 06:00:00, BdApbp, LocSup ************************************* Cas d'un fichier au format 'long' >>> f = 'data/data/lamedo/bp_long.json' >>> series = read_BdApbp(filename=f, zones=['41005']) >>> series ************************************* ********** SERIES ******************* ************************************* * NOM DE LA COLLECTION = BdApbp * TYPE DE COLLECTION = fcst * NOMBRE DE SERIES = 8 * ---------------------------------- * SERIE #1 * - CODE = 41003 * - VARNAME = PJ * - META = 2020-06-12 05:26:00, BdApbp, MoyInf * ---------------------------------- * SERIE #2 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 05:26:00, BdApbp, MoyInf * ---------------------------------- * SERIE #3 * - CODE = 41003 * - VARNAME = PJ * - META = 2020-06-12 05:26:00, BdApbp, MoySup * ---------------------------------- * SERIE #4 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 05:26:00, BdApbp, MoySup * ---------------------------------- * SERIE #5 * - CODE = 41003 * - VARNAME = PJ * - META = 2020-06-12 05:26:00, BdApbp, LocInf * ---------------------------------- * SERIE #6 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 05:26:00, BdApbp, LocInf * ---------------------------------- * SERIE #7 * - CODE = 41003 * - VARNAME = PJ * - META = 2020-06-12 05:26:00, BdApbp, LocSup * ---------------------------------- * SERIE #8 * - CODE = 41005 * - VARNAME = PJ * - META = 2020-06-12 05:26:00, BdApbp, LocSup ************************************* """ # ------------------------------------------------------------------------- # 0- Contrôles # ------------------------------------------------------------------------- _exception.check_str(filename) if zones is not None: _exception.check_listlike(zones) _exception.check_bool(warning) # ------------------------------------------------------------------------- # 1- Lecture # ------------------------------------------------------------------------- # Création du lecteur reader = BdApbp(filename=filename) # Lecture des données df = reader.read() # ------------------------------------------------------------------------- # 2- Transformation du DataFrame # ------------------------------------------------------------------------- # Récupération du format du BP datatype = reader._datatype # Récupérer les dates de production par zone runtimes = {x[0]: x[1].to_pydatetime() for x in df[['CODE', 'DTPROD']].values} # Définir BP[Moy,Loc][Inf,Sup] col = df.apply(list_values, axis=1) df = df.assign(VALUE=col.values) # VALUE : colonne avec les 4 valeurs df[BDAPBP_SCENS] = pnd.DataFrame(df.VALUE.to_list(), index=df.index) # Colonne 'DATE' -> Index df = df.set_index(keys='DATE', drop=True) df.index = [i - td(days=1) for i in df.index] # Nettoyer les colonnes superflues df = df.drop(columns=['NAME', 'DTPROD', # 'DATE', 'MOY', 'DELTA', 'LOC', 'LOCDELTA', 'VALUE']) # Colonne 'Code' -> Multi-Index (None, Code) avec None: ['Debit (l/s)'] df = df.pivot(columns='CODE') # MultiIndex : (CODE, VAR) df.columns = df.columns.swaplevel() # ------------------------------------------------------------------------- # 3- Conversion en Series # ------------------------------------------------------------------------- series = Series(datatype='fcst', name='BdApbp') for c in df.columns: zone = c[0] if isinstance(zones, list) and zone not in zones: continue scen = c[1] runtime = runtimes[zone] d = df[c].to_frame() try: serie = Serie(d, code=zone, provider='BdApbp', varname=datatype, warning=warning) except ValueError: continue series.add(serie=serie, meta=(runtime, 'BdApbp', scen)) return series
def list_values(row): """ Définir les valeurs 'MoyInf', 'MoySup', 'LocInf', 'LocSup'. Selon les colonnes 'MOY', 'DELTA', 'LOC', 'LOCDELTA' Parameters ---------- row : pandas.Series Ligne d'un tableau de données Returns ------- list Valeurs 'MoyInf', 'MoySup', 'LocInf', 'LocSup' """ ratio = 0.1 # 1/10 mm => mm md = row['DELTA'] if np.isnan(md) or md is None: md = 0 ld = row['LOCDELTA'] if np.isnan(ld) or ld is None: ld = 0 mi = ratio * (row['MOY'] - md) ms = ratio * (row['MOY'] + md) li = ratio * (row['LOC'] - ld) ls = ratio * (row['LOC'] + ld) return [mi, ms, li, ls] def set_ltime(row): """ Définir l'échéance en fonction de la date cible et de la date de prod. Parameters ---------- row : pandas.Series Ligne d'un tableau de données Returns ------- int Echéance de la prévision """ ref = row['DTPROD'] target = row['DATE'] ltime = int((target - ref) / td(days=1)) return ltime