Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

partons d’un jeu de données réel qui décrit des grandeurs géophysiques sur une période plus de 10 ans avec une fréquence de 1h

pd.read_excel

ce qui va nous donner une occasion de travailler sur un fichier .xlsx
pour cela le point d’entrée c’est pd.read_excel, mais il faut savoir que cela demande une dépendance supplémentaire

du coup si nécessaire, faites l’installation de openpyxl comme indiqué, par exemple:

chargement

le premier chargement “naif” avec read_excel nous permet de voir que la donnée temporelle ressemble à ceci

18/08/2006 21:00

aussi on va utiliser ce format pour charger “proprement” notre dataframe; cela va avoir deux avantages

Loading...

pour info, les données en question signifient ceci:

colonnenom complet
NPNiveau Puits
PAPression Atmosphérique
MGMarée Océanique (Marée Géographique)
ETMarée terrestre (Earth Tide)
<class 'pandas.DataFrame'>
RangeIndex: 117188 entries, 0 to 117187
Data columns (total 5 columns):
 #   Column             Non-Null Count   Dtype         
---  ------             --------------   -----         
 0   Date_Heure_locale  117188 non-null  datetime64[us]
 1   NP                 116096 non-null  object        
 2   PA                 114921 non-null  float64       
 3   MG                 115843 non-null  float64       
 4   ET                 117188 non-null  float64       
dtypes: datetime64[us](1), float64(3), object(1)
memory usage: 4.5+ MB

ça fait tout de même 120.000 entrées de 4 mesures chacune; ça ne va pas être possible de faire une inspection visuelle de tout ça

voyons un peu le genre de chose qu’on peut faire automatiquement pour s’assurer de la complétude / cohérence de ces données

préparation

pour commencer, la todo list est souvent celle-ci:

ici notre colonne candidat pour être l’index, c’est cette colonne temporelle, c’est vraiment naturel

unicité ?

Date_Heure_locale 2007-03-25 01:00:00 2 2008-03-30 01:00:00 2 2009-03-29 01:00:00 2 2010-03-28 01:00:00 2 2011-03-27 01:00:00 2 2012-03-25 01:00:00 2 2013-03-31 01:00:00 2 2014-03-30 01:00:00 2 2015-03-29 01:00:00 2 2016-03-27 01:00:00 2 2017-03-26 01:00:00 2 2018-03-25 01:00:00 2 2019-03-31 01:00:00 2 Name: count, dtype: int64
13
Loading...

mmh, c’est assez étrange, les 3 premières colonnes ont des données quasi identiques au moment du doublon, mais pas la 4ème...

compte tenu du faible nombre de lignes concernées, on va prendre une décision conservatoire, qui est de garder, pour chacun de ces 13 instants, la moyenne des deux mesures

sauf que, si on essaie de faire ça ce stade, on est confronté au fait que la colonne NP est de type object...

une colonne de type object

Date_Heure_locale datetime64[us] NP object PA float64 MG float64 ET float64 dtype: object

pour bien trouver tous les soucis avec cette colonne:

OOPS <class 'ValueError'> exc=ValueError('Unable to parse string " " at position 1695')

ce qui nous indique qu’il y a au moins un endroit où la colonne NP contient une chaine composée d’un espace; voyons combien il y en a de ce genre

NP False 113624 True 3564 Name: count, dtype: int64

fort heureusement on peut forcer la conversion comme ceci

0 4.600 1 4.600 2 4.600 3 4.600 4 4.600 ... 117183 4.662 117184 4.661 117185 4.663 117186 4.663 117187 4.662 Name: NP, Length: 117188, dtype: float64

cette fois la conversion se fait correctement; il ne faut pas oublier par contre de bien adopter la nouvelle colonne - car avec la cellule précédente on a calculé un nouvelle colonne mais elle ne fait pas partie de la dataframe

Date_Heure_locale datetime64[us] NP float64 PA float64 MG float64 ET float64 dtype: object

la moyenne

on peut à présent faire la moyenne pour les doublons

Loading...
OK !

c’est terminé

et on n’a même pas besoin d’adopter l’index puisque ça a déjà été fait par le groupby..

Loading...

aperçu

notre objectif: passer le moins de temps possible pour voir une vague idée de ces données

<Figure size 640x480 with 1 Axes>

la première amélioration vient au prix d’une ligne qu’on mentionne généralement au début (autour de par exemple la ligne import pandas as pd)

%matplotlib ipympl pour des graphiques interactifs

Loading...

figsize

si vous voulez choisir une taille par défaut pour les figures

Loading...
Loading...

subplots=True

comme les échelles ne sont pas forcément les mêmes, ou pour plein d’autres raisons, on peut avoir envie de voir les données indépendamment les unes des autres

Loading...

alpha=0.1

si on insiste pour voir les 4 données dans la même vue, comme on avait fait pour commencer, il y a tellement de données en X qu’on ne voit que la dernière colonne !
dans ces cas-là le canal alpha (la transparence) est notre meilleur allié

Loading...

les trous dans la donnée (aka nan)

à ce stade on a donc des nan - au moins dans NP, ça on en est sûr, et dans les autres colonnes peut-être aussi

np.int64(4656)
NP 4656 PA 2267 MG 1345 ET 0 dtype: int64

comment les calculer ?

ce qu’on aimerait savoir maintenant, c’est est-ce que les ‘trous’ sont plutôt éparpillés ou plutôt groupés; et pour ça on va

si on avait une série parfaitement pleine, on n’obtiendrait que des valeurs de “1h” dans ce résultat
et donc en éliminant de cela les valeurs “1h”, on obtient la liste des trous dans la donnée (c’est-à-dire quand y a-t-il eu un trou, et combien de temps a-t-il duré)

((117175,), (112519,))
Date_Heure_locale 2006-08-18 00:00:00 2006-08-18 00:00:00 2006-08-18 01:00:00 2006-08-18 01:00:00 2006-08-18 02:00:00 2006-08-18 02:00:00 2006-08-18 03:00:00 2006-08-18 03:00:00 2006-08-18 04:00:00 2006-08-18 04:00:00 ... 2019-12-30 15:00:00 2019-12-30 15:00:00 2019-12-30 16:00:00 2019-12-30 16:00:00 2019-12-30 17:00:00 2019-12-30 17:00:00 2019-12-30 18:00:00 2019-12-30 18:00:00 2019-12-30 19:00:00 2019-12-30 19:00:00 Name: Date_Heure_locale, Length: 112519, dtype: datetime64[us]

on décale

Date_Heure_locale 2006-08-18 00:00:00 NaT 2006-08-18 01:00:00 2006-08-18 00:00:00 2006-08-18 02:00:00 2006-08-18 01:00:00 2006-08-18 03:00:00 2006-08-18 02:00:00 2006-08-18 04:00:00 2006-08-18 03:00:00 ... 2019-12-30 15:00:00 2019-12-30 14:00:00 2019-12-30 16:00:00 2019-12-30 15:00:00 2019-12-30 17:00:00 2019-12-30 16:00:00 2019-12-30 18:00:00 2019-12-30 17:00:00 2019-12-30 19:00:00 2019-12-30 18:00:00 Name: Date_Heure_locale, Length: 112519, dtype: datetime64[us]
Date_Heure_locale 2006-08-18 00:00:00 NaT 2006-08-18 01:00:00 0 days 01:00:00 2006-08-18 02:00:00 0 days 01:00:00 Name: Date_Heure_locale, dtype: timedelta64[us]

digression: comment fabriquer un timedelta

Timedelta('0 days 01:00:00')
Timedelta('0 days 01:00:00')

reprenons

nous en sommes donc au stade où on veut enlever de delta les valeurs correspondant à 1h

nous avons trouvé 76 trous dans la colonne NP
Date_Heure_locale 2006-11-06 08:00:00 9 days 18:00:00 2006-11-24 12:00:00 0 days 07:00:00 2007-03-25 03:00:00 0 days 02:00:00 2007-04-13 01:00:00 10 days 17:00:00 2007-06-25 01:00:00 27 days 17:00:00 ... 2019-08-30 14:00:00 0 days 02:00:00 2019-09-07 03:00:00 1 days 08:00:00 2019-09-17 02:00:00 2 days 00:00:00 2019-09-24 10:00:00 2 days 01:00:00 2019-11-07 00:00:00 8 days 01:00:00 Name: Date_Heure_locale, Length: 76, dtype: timedelta64[us]

on les affiche

Loading...

question

utilisez le zoom pour trouver à quelle époque a eu lieu la coupure la plus longue dans l’acquisition de NP

the longest outage was 79 days 15:00:00 long and occurred on 2012-06-26 14:00:00

un peu de lissage

on regarde cette fois la courbe ‘PA’; utilisez le zoom pour regarder environ un mois

Loading...

on voit que la fluctuation en tendance est obscurcie par des variations de plus haute fréquence; on va essayer de lisser ce signal pour ne conserver que la tendance de fond

normalement si vous zoomez encore davantage, vous devriez percevoir que la haute fréquence est de l’ordre de la demie journée

rolling

on va calculer le rolling de ce signal avec deux périodes (12h et 24h), et afficher tout cela

Loading...

à nouveau, je vous invite à zoomer dans le graphique pour juger de la pertinence de chacune de ces deux approximations

laquelle garderiez-vous ?