2.4.2. Exercice 4 - Fonction et calcul scientifique#
2.4.2.1. Numpy pour le calcul scientifique et Matplotlib#
Objectifs d’apprentissage
Créer de nouveaux tableaux en utilisant
linspace
etarange
.Calculer des formules de base avec les tableaux
numpy
. Charger des données à partir de fichiers.npy
* Effectuer des réductions (par exemple.npy
)Effectuer des réductions (par exemple
mean
,std
sur les tableauxnumpy
)Réaliser des tracés linéaires 1D
Réaliser des diagrammes de dispersion
Annoter les graphiques avec des titres et des axes
Dans ce problème, nous utilisons des données réelles provenant de flotteurs de profilage océanique. Les flotteurs ARGO sont des instruments robotiques autonomes qui recueillent des données sur la température, la salinité et la pression de l’océan. Les flotteurs ARGO recueillent un “profil” (un ensemble de mesures à différentes profondeurs ou “niveaux”).
Chaque profil est associé à une latitude, une longitude et une date, ainsi qu’à de nombreux niveaux différents.
Commençons par utiliser pooch pour télécharger les fichiers de données dont nous avons besoin pour cet exercice. Le code suivant vous donnera une liste de fichiers .npy
que vous pourrez ouvrir à l’étape suivante.
import pooch
url = "https://unils-my.sharepoint.com/:u:/g/personal/tom_beucler_unil_ch/EZwbaBqass1LhZO3DS3BCL0BhIlcENuoDItMB9b4IYDUCQ?download=1"
files = pooch.retrieve(url, processor=pooch.Unzip(), known_hash='2a703c720302c682f1662181d329c9f22f9f10e1539dc2d6082160a469165009')
files
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[1], line 1
----> 1 import pooch
3 url = "https://unils-my.sharepoint.com/:u:/g/personal/tom_beucler_unil_ch/EZwbaBqass1LhZO3DS3BCL0BhIlcENuoDItMB9b4IYDUCQ?download=1"
4 files = pooch.retrieve(url, processor=pooch.Unzip(), known_hash='2a703c720302c682f1662181d329c9f22f9f10e1539dc2d6082160a469165009')
ModuleNotFoundError: No module named 'pooch'
import numpy as np
Q1) Chargez chaque fichier de données sous la forme d’un tableau numpy
.
Vous pouvez utiliser les noms que vous voulez pour vos tableaux, mais nous recommandons :
T
: température
S
: salinité
P
: pression
date
: date
lat
: latitude
lon
: longitude
level
: niveau de profondeur
Astuce 1 : Regardez le nom du fichier (les éléments dans files
) pour savoir quel fichier correspond à quelle variable.
Astuce 2 : Consultez la documentation de np.load
.
Affichez les noms des éléments des fichiers ici
___
Ensuite, chargez les fichiers sous forme de tableaux numpy
, par exemple en utilisant la compréhension de liste
#@title Code à compléter (au besoin)
___,___,___,___,___,___,___ = [np.___(___[___]) for ___ in range(___)]
Q2) Recréez le tableau level
en utilisant np.arange
et np.linspace
.
Conseils :
La documentation de
np.arange
est at this linkLa documentation pour
np.linspace
est à ce lienLa documentation pour
np.testing.assert_equal
est at this link
Affichez le tableau level
(niveau)
___
Recréez le tableau level
en utilisant np.arange
et l’appeler level_arange
#@title Code à compléter (au besoin)
level_arange = np.arange(___,___)
Vérifiez que level
et level_arange
sont égaux en utilisant np.testing.assert_equal
#@title Code à compléter (au besoin)
np.___.___(___,level_arange)
Recréer le tableau level
en utilisant np.linspace
et l’appeler level_linspace
#@title Code à compléter (au besoin)
___ = np.___(___,___,___)
Vérifiez que level
et level_linspace
sont égaux en utilisant np.testing.assert_equal
#@title Code à compléter (au besoin)
___.___(___,___)
Q3) Examinez les formes de T
, S
et P
par rapport à lon
, lat
, date
et niveau
. Comment pensez-vous qu’ils sont liés ?
Indice : consultez la sous-section NDArrays
Affichez les formes de toutes les variables chargées
#@title Code à compléter (au besoin)
___.shape
___.___
D’après les formes, quelles sont les dimensions partagées entre les tableaux ?
Q4) En vous basant sur la formule ci-dessous, calculez la densité de l’eau de mer relative_density
, par rapport à l’eau pure, en fonction de la température, de la salinité et de la pression.
densité_relative
\( = ρ -ρ_{Eau pure} = a \times S +b \times \Theta + c \times \Theta^{2}\)
où :
Les densités \(\rho\) et \(ρ_{Pure\ eau}\) sont exprimées en unités \(kg/m^{3}\).
Les constantes \(a\), \(b\) et \(c\) sont fournies ci-dessous.
La fonction permettant de calculer la température conservative \(\Theta\) (en unités Celcius) à partir de la température, de la salinité et de la pression est fournie ci-dessous.
La température \(T\) est exprimée en unités Celcius.
La salinité \(S\) est exprimée en unités \(g/kg\).
La pression \(p\) est exprimée en unités \(dbar\).
Astuce : Les tableaux numpy
chargés temperature
, salinity
, et pressure
ont déjà les bonnes unités et aucune conversion n’est nécessaire.
Sources :
The Gibbs SeaWater (GSW) Oceanographic Toolbox of TEOS-10. (Licence)](https://www.teos-10.org/pubs/gsw/html/gsw_licence.html)
Voici les constantes a, b et c :
a = 7.718e-1
b = -8.44e-2
c = -4.561e-3
Importons la bibliothèque [gsw
] (https://teos-10.github.io/GSW-Python/) qui contient la fonction CS_from_t
pour calculer la température conservative \(\Theta\) à partir de la température, de la salinité et de la pression.
!pip install gsw
from gsw import CT_from_t
Maintenant, c’est à vous de jouer. Voici l’équation pour éviter d’avoir à faire défiler la page vers le haut :
densité_relative
\( = ρ -ρ_{Pure\ Eau} = a \times S +b \times \Theta + c \times \Theta^{2}\)
Calculeuz la température conservatrice
Conseil : utilisez CT_from_t
#@title Code à compléter (au besoin)
___ = CT_from_t(___,___,___)
Calculez la “densité relative” à l’aide de l’équation ci-dessus.
#@title Code à compléter (au besoin)
___ = ___
Q4) Faites un graphique pour chaque colonne de données dans T
, S
, P
, et
densité_relative
(quatre plots)
Pour cette question, nous devons utiliser l’interface Pyplot de la bibliothèque Matplotlib pour la visualisation, même si nous ne l’avons pas encore étudiée en profondeur en classe. Mais n’ayez crainte, nous vous fournissons des instructions faciles à suivre ci-dessous. 😊
La première étape consiste à importer Pyplot. Il suffit d’exécuter le code ci-dessous.
import matplotlib.pyplot as plt
Ensuite, nous tracerons les variables en fonction de la profondeur de l’océan, level
. Il suffit de lire la documentation [sur ce lien] (https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html) pour en déduire la syntaxe correcte. Etiquetez vos axes en utilisant plt.xlabel
et plt.ylabel
, et ajoutez un titre en utilisant plt.title
.
Astuce : L’échelle verticale doit utiliser les données level
pour être cohérente avec les conventions océanographiques.
Conseil 2 : Chaque graphique doit avoir une ligne pour chaque colonne de données. Le résultat sera désordonné, comme dans le graphique ci-dessous :
plt.plot(___,___) ; # Le point-virgule empêche l'impression des objets de ligne
plt.xlabel(___) # Prend une chaîne de caractères comme argument
plt.ylabel(___)
plt.title(___)
Faites plus de plots ci-dessous:
**Q5) Calculez la moyenne et l’écart-type de T
, S
, P
, et seawater_density
à chaque profondeur dans level
.
Conseil : Vous pouvez lire la documentation sur ce lien et ce lien.
Conseil 2 : Vous pouvez vérifier que vous avez pris la moyenne et les écarts types le long des axes corrects en vérifiant la “forme” de vos résultats.
Calculez les moyennes…
#@title Code à compléter (au besoin)
___ = np.___(___,axis=___)
___
___
___
… et les écarts types.
#@title Code à compléter (au besoin)
___ = ___.___(___,___)
Vérifiez qu’elles ont la même forme que vos coordonnées de niveau vertical lev
:
#@title Code à compléter (au besoin)
np.testing.assert_equal(___.shape,lev.shape)
Q6) Faites maintenant des tracés similaires, mais ne montrez que les moyennes T
, S
, P
, et densité_de_l'eau_de_mer
à chaque profondeur. Faites apparaître les barres d’erreur sur chaque graphique en utilisant les écarts-types.
Astuce : Si vous vous sentez aventureux, vous pouvez utiliser directement la fonction plt.errorbar
.
Astuce 2 : Vous devriez obtenir des graphiques similaires à celui ci-dessous
plt.errorbar(___,___,xerr=___)
plt.xlabel(___)
plt.ylabel(___)
plt.title(___)
Encore trois plots et nous serons prêts 🙂 .
Q7) Prise en compte des données manquantes
Les profils contiennent de nombreuses valeurs manquantes. Celles-ci sont indiquées par la valeur spéciale “Not a Number”, ou np.nan
.
Lorsque vous prenez la moyenne ou l’écart type des données contenant des NaN, le résultat entier devient NaN
. Au lieu de cela, si vous utilisez les fonctions spéciales np.nanmean
et np.nanstd
, vous dites à NumPy d’ignorer les NaN.
Recalculez les moyennes et les écarts types comme dans les sections précédentes en utilisant ces fonctions et tracez les résultats.
Conseil : Liens vers la documentation np.nanmean
et la documentation np.nanstd
.
Recalculez les moyennes ci-dessous en ignorant les valeurs manquantes. Nous espérons que vous pouvez maintenant trouver la syntaxe complète vous-même 😎
De même, recalculez les écarts types en ignorant les valeurs manquantes.
Q8) Créez un diagramme de dispersion des coordonnées longitudinales (lon
) et latitudinales (lat
) des flotteurs ARGO.
Encore une fois, nous n’en avons pas parlé dans le tutoriel, mais il existe une fonction de diagramme de dispersion très pratique appelée plt.scatter
fournie par l’interface Pyplot.
Bonus : Etiqueter votre figure en utilisant plt.xlabel
, plt.ylabel
, et plt.title
.
Bonus 2 : Augmentez la taille de police de vos étiquettes en ajoutant un argument fontsize=
aux fonctions d’étiquettes.
Bonus 3 : Rendez votre diagramme de dispersion plus beau en changeant les arguments de plt.scatter
listés dans la documentation, par exemple s=
.
#@title Code à compléter (au besoin)
plt.scatter(___,___)
___ # Bonus
___ # Plus de bonus
2.4.2.2. Fonctions#
Q1) Ecrivez une fonction pour convertir l’unité que vous avez choisie pour les masses planétaires en \(M_{Terre}\), la masse de la Terre.
Par exemple, la masse de Jupiter est :
\(M_{Jupiter} \approx 1898\times10^{24}kg \approx 318 M_{Terre}\)
planetdict = {'mercure':0.330,'vénus':4.87,'terre':5.97,
'mars':0.642,'jupiter':1898,'saturne':568,'uranus':86.8,'nepturne':102, 'pluto':0.013}
# unit: 10^24 kg
# Ecrivez votre fonction ici
# La fonction doit prendre la masse de la planète que vous voulez (par exemple, planetdict['mars']) et la diviser par la masse de la Terre.
# (planetdict['terre'])
# Testez que cela fonctionne pour jupiter (planetdict['jupiter']), la fonction devrait retourner 317.92294807370183
#@title Code à compléter (au besoin)
# Ecrivez votre fonction ici
# La fonction doit prendre la masse de la planète que vous voulez (par exemple, planetdict['mars']) et la diviser par la masse de la Terre.
# (planetdict['terre'])
def convert_mass_Mterre(______=____):
return _________/planetdict['terre']
#tester que cela fonctionne pour jupiter (planetdict['jupiter']), la fonction devrait retourner 317.92294807370183
convert_mass_Mterre(____________)
Q2) Ecrivez maintenant une fonction unique qui peut convertir l’unité que vous avez choisie pour les masses planétaires en \(M_{Terre}\) ou \(M_{Jupiter}\) selon le mot-clé que vous avez spécifié.
# Écrivez votre fonction ici
# Vérifiez que votre fonction fonctionne : convertissez Mjupiter en Mterre et Mjupiter,
# Vous devriez voir 317.923 (Mterre) et 1.0 (Mjupiter)
#@title Code à compléter (au besoin)
# Écrivez votre fonction ici
def convert_m_Mterrejupiter(______=____,ourplanet='jupiter') :
return ___________/planetdict[ourplanet]
# Vérifiez que votre fonction fonctionne : convertissez Mjupiter en Mterre et Mjupiter,
# Vous devriez voir 317.923 (Mterre) et 1.0 (Mjupiter)
print(convert_m_Mterrejupiter(planetdict['jupiter'],_____),convert_m_Mterrejupiter(planetdict['jupiter'],______))
# Stocker le Mjupiter pour Q3
Mjupiter = convert_m_Mterrejupiter(planetdict['jupiter'], 'jupiter')
**Q3) Ecrivez une fonction qui prend un argument (la masse en \(M_{Jupiter}\)) et renvoie deux arguments (la masse en \(M_{Terre}\) et la masse dans l’unité que vous avez choisie [la planète que vous voulez]).
# Écrivez votre fonction ici
# Vérifiez que la conversion de la masse de Jupiter en $M_{Terre}$ et en $M_{Terre}$ fonctionne.
# l'unité choisie (par exemple, la planète Mars)
#@title Code à compléter (au besoin)
# Écrivez votre fonction ici
def mass_conversion_two_arguments(mass,planet=____) :
a = mass/planetdict[_____] # Terre
b = mass/planetdict[______] # La planète que vous voulez utiliser comme référence
return a,b
# Vérifiez que la conversion de la masse de Jupiter en $M_{Terre}$ et en $M_{Terre}$ fonctionne.
# l'unité choisie (par exemple, la planète Mars)
print(mass_conversion_two_arguments(_____,'mars'))
# Bonus : Utilisez la fonction de Q10 pour convertir la masse de Neptune en $M_{Jupiter}$.
# puis la fonction de Q3 pour la reconvertir dans l'unité que vous avez choisie
# Retrouvez-vous la valeur originale ?