{ "cells": [ { "cell_type": "markdown", "metadata": { "nbpages": { "level": 1, "link": "[1.1 Getting Started with Python and Jupyter Notebooks](https://jckantor.github.io/CBE30338/01.01-Getting-Started-with-Python-and-Jupyter-Notebooks.html#1.1-Getting-Started-with-Python-and-Jupyter-Notebooks)", "section": "1.1 Getting Started with Python and Jupyter Notebooks" }, "slideshow": { "slide_type": "slide" } }, "source": [ "# TP0 Introduction à python et Jupyter notebook" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 2, "link": "[1.1.1 Summary](https://jckantor.github.io/CBE30338/01.01-Getting-Started-with-Python-and-Jupyter-Notebooks.html#1.1.1-Summary)", "section": "1.1.1 Summary" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Instructions pour le devoir\n", "\n", "Ce travail pratique vise à vous introduire à python et au notebook Jupyter. Nous ferons un tour d'horizon des fonctions nécessaires aux travaux pratiques, en évitant le plus possible de devenir un cours de programmation.\n", "\n", "Voici les instructions \n", "- Remplissez vos réponses dans les cellules indiquées. Les réponses peuvent prendre la forme d'un segment de code ou d'une réponse textuelle, ou les deux.\n", "- Bien commenter les cellules de code afin de décrire la démarche.\n", "- Assurez-vous que chaque cellule s'exécute et donne la réponse désirée avant de remettre votre notebook. Pour ce faire, il est recommandé d'exécuter `Kernel` -> `Restart and Run All`.\n", "- Vous devez remettre les fichiers du jupyter notebook complété (.ipynb), ainsi que sa version pdf (`File` -> `Download as` -> `PDF`).\n", "- Ce travail doit être fait de façon individuelle, chaque personne doit remettre sa propre copie." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Quelques références utiles\n", "\n", "* [Jupyter Notebook](https://jupyter.org)\n", "* [Numpy](https://numpy.org)\n", "* [Matplotlib](http://matplotlib.org/index.html) \n", "* [Pygimli](https://www.pygimli.org) \n", "* [StackOverflow](https://stackoverflow.com)\n", "\n", "Enfin, voici un vidéo introduisant les Jupyter Notebook, facultatif." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "from IPython.display import YouTubeVideo\n", "YouTubeVideo(\"HW29067qVWk\",560,315,rel=0)" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 2, "link": "[1.1.2 Step 0: Gain Executable Access to Jupyter Notebooks](https://jckantor.github.io/CBE30338/01.01-Getting-Started-with-Python-and-Jupyter-Notebooks.html#1.1.2-Step-0:-Gain-Executable-Access-to-Jupyter-Notebooks)", "section": "1.1.2 Step 0: Gain Executable Access to Jupyter Notebooks" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## 1.0 Le Jupyter notebook\n", "\n", "Un notebook Jupyter est un document permettant d'exécuter des lignes de code, afficher des résultats sous la forme de graphique et commenter avec du texte formaté, tout ça à l'intérieur d'un fureteur web. Habituellement, le langage utilisé est python. C'est ce que nous ferons dans ce cours. Voici quelques fonctionnalités nécessaires à maitriser pour le cours." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1 Exécution d'une cellule\n", "\n", "Un notebook est divisé en cellules, qui peuvent être exécutées de façon indépendantes. Afin d'exécuter une cellule, il suffit de cliquer sur la cellule pour la sélectionner, puis de tapper `shift`+`enter`. Essayez avec la cellule suivante." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "print(\"hello\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Une cellule peut aussi être éditée afin de modifier le code qui sera exécuté. Remplacez dans la cellule suivante la variable `nom` par votre nom, puis exécutez la cellule." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "nom = \"mon_nom\"\n", "print(nom)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Une cellule peut être exécutée autant de fois que vous le désirez, dans l'ordre que vous désirez. Remarquez le nombre à gauche de la cellule; il indique l'ordre dans lequel les cellules ont été exécutées. Faites attention, si différentes cellules utilisent les mêmes variables et les redéfinissent, l'ordre dans lequel les cellules ont été exécutées importe! En guise d'exemple, la variable `x` qui sera imprimée à la troisième cellule dépendra de laquelle des deux cellules précédentes aura été exécutée. Essayez de faire en sorte que le nombre imprimé soit 1, sans changer le contenu des cellulles." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "x = 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "x = 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "En bref, toute variable définie dans une cellule qui a été exécutée est gardée en mémoire et est accessible dans les autres cellules." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.2 Cellule de texte\n", "\n", "Comme vous le constatez, un notebook peut aussi contenir du texte. Ce texte est aussi contenu dans une cellule, de format différent. En effet, lorsqu'on crée une cellule, on peut choisir entre deux types: Codes ou Markdown. Une cellule code est une cellule contenant du code python exécutable, tandis qu'une cellule Mardown est une cellule contenant du texte formaté en Markdown." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Une cellule Markdown peut être éditée de la même façon qu'une cellule de code; avec un double clic. Vous pouvez essayer sur n'importe quelle cellule de ce notebook. Vous remarquerez alors que la cellule change d'aspect le texte brut en format Markdown apparaît. Vous pouvez alors éditer le texte qui apparait puis exécuter la cellule pour voir le texte formaté." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vous n'avez pas besoin de maitriser le formatage Markdown dans ce cours. Si vous voulez en connaître plus, regardez les différentes cellules des notebook de TP. Aussi, dans le menu du notebook, si vous allez dans `Help`->`Markdown`, vous pourrez avoir différentes informations pour pousser plus loin vos compétences." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Une fonctionnalité Markdown qui pourrait vous être utile est la prise en charge de Latex. Il est ainsi facile d'écrire une équation. Deux utilisations sont possibles.\n", "- Une équation non-indentée qui peut être contenue dans un texte, comme par exemple $\\rho=1 kg/m^3$. Dans ce cas, le code Latex doit être délimité de part et d'autre par le symbole $,\n", "- Une équation indentée, qui peut être décrit par un environnement \\\\begin\\{align\\} \\\\ end\\{align\\}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Par exemple, cette cellule montre comment écrire une équation indentée:\n", "\n", "\\begin{align}\n", "\\nabla^2 U = 4 \\pi G \\rho\n", "\\end{align}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.3 Ajout de cellule\n", "\n", "Il est simple d'ajouter une cellule grâce au menu de Jupyter. Si vous cliquer sur une cellule, puis aller dans le menu `Insert` -> `Insert Cell Below`. Ce menu indique aussi qu'il existe des raccourcis claviers pour le faire (`Esc`+`A` et `Esc`+`B`). Tous les racourcis sont disponibles dans `Help` -> `Keyboard Shorcuts`. Lorsqu'une cellule est créée, il est possible de modifier le type de cellule avec la bulle grise en dessus du menu contextuel.\n", "\n", "Ajoutez une cellule ci-bas pour tester cette fonctionnalité. Changer au type Markdown, puis écrire votre nom." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il est aussi simple d'enlever une cellule. Pour ce faire, cliquer sur une cellule, puis aller dans `Edit` -> `Delete Cells`, ou simplement appuyer sur `Esc`+`D`+`D`. Pour vous pratiquer, effacez la cellule suivante." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "# Enlevez cette cellule" ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 2, "link": "[1.1.4 Step 2: Simple Calculations with Python](https://jckantor.github.io/CBE30338/01.01-Getting-Started-with-Python-and-Jupyter-Notebooks.html#1.1.4-Step-2:-Simple-Calculations-with-Python)", "section": "1.1.4 Step 2: Simple Calculations with Python" } }, "source": [ "## 2.0 Python\n", "\n", "Python est un langage de programmation simple et efficace. C'est un des langages les plus utilisé au monde, et il existe des milliers de librairies donnant accès à toute sorte de fonctionnalités. Tout ça, en open source, donc gratuitement.\n", "\n", "Python partage avec Matlab sa simplicité et beaucoup de sa syntaxe. Vous ne serez donc pas trop dépaysé si vous connaissez déjà Matlab. Cependant, il existe de nombreuses différences. Dans les prochaines cellules, nous ferons un tour d'horizon des différentes fonctionnalités nécessaires pour compléter les travaux pratiques." ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[1.1.4.1 Basic Arithmetic Operations](https://jckantor.github.io/CBE30338/01.01-Getting-Started-with-Python-and-Jupyter-Notebooks.html#1.1.4.1-Basic-Arithmetic-Operations)", "section": "1.1.4.1 Basic Arithmetic Operations" } }, "source": [ "### 2.1 Opérations arithmétiques de base\n", "\n", "Les opérations arithmétiques de base sont bien sur offertes par défaut en python. En voici quelques exemples. Notez que l'exponentiation se fait par l'opérateur \\*\\*, et non pas \\^ comme en Matlab." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpages": { "level": 3, "link": "[1.1.4.1 Basic Arithmetic Operations](https://jckantor.github.io/CBE30338/01.01-Getting-Started-with-Python-and-Jupyter-Notebooks.html#1.1.4.1-Basic-Arithmetic-Operations)", "section": "1.1.4.1 Basic Arithmetic Operations" }, "scrolled": false }, "outputs": [], "source": [ "a = 12\n", "b = 2\n", "\n", "print(a + b)\n", "print(a**2)\n", "print(a/b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.2 Opérations logiques\n", "\n", "Il est aussi possible d'effectuer des opérations logiques de base." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "print(1>2)\n", "print(1==1)\n", "print(1!=1)\n", "print(1>=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.3 Boucles\n", "\n", "Les boucles sont aussi faciles à utiliser en python. En python, le corps d'une boucle est indiqué par l'identation du code, qui doit être indenté d'une tabulation (4 espaces) par rapport à son énoncé. La ligne énonçant la boucle doit être terminée par un `:`. Voici un exemple:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "for ii in range(3):\n", " print(ii)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notez l'opérateur `in` qui indique d'inspecter les éléments de la variable qui suit. Dans ce cas, cette variable est obtenue par la fonction `range` qui crée un itérable comprenant (0,1,2). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.4 Fonctions\n", "\n", "Il est aussi possible de définir des fonctions. Comme dans le cas des boucles, le corps d'une fonction doit être indentée par rapport à sa définion. Par exemple:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "def fun(x, b=1):\n", " return x+b\n", "\n", "print(fun(2))\n", "print(fun(2, b=2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notez que la fonction retourne les variables suivant la mention `return`. La fonction précédente montre l'utilisation d'un argument facultatif (`b`). Ceci permet d'omettre cet argument lorsque la fonction est appelée, dans lequel cas elle prend la valeur par défaut indiquée dans la déclaration (1 ici). Pour appeler une fonction avec un argument optionnel, le nom de l'option doit être explicitement mentionné (`fun(2, b=1)`)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.5 Types de variable\n", "\n", "Contrairement à Matlab où tout est un vecteur ou une matrice, Python inclut plusieurs types de variables. Voici une courte liste.\n", "\n", "- Les scalaires (int, float, complex, bool) : `1`, `5.0` ...\n", "- Les caractères (string), qui sont délimités soit par `\"string\"` ou `'string'`\n", "- Les listes, qui regroupent une suite de variables, `[1, 2, 3]`\n", "- Les dictionnaires, qui regroupent plusieurs objets sous un nom `{'a': 1, 'b':2}`\n", "- Les objets, qui regroupent des variables et des fonctions\n", "\n", "Nous ferons un bref tour d'horizon ici. Vous pouvez toujours vérifier quel est le type de variable dont vous avez affaire avec la fonction `type`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "print(type(1.0))\n", "print(type(1))\n", "print(type([1]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On voit ici que nous avons affaire à deux types de scalaires, un int et un float (un entier et un nombre à virgule) et une liste. Remarquez que ces deux types sont en fait des classes (soit des objets). En fait, tout est une classe dans python..., mais ici on digresse. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.6 Les listes\n", "\n", "Regardons un peu plus en détails ce que sont les listes. Attention, on pourrait penser qu'une liste est la même chose qu'un vecteur en Matlab. Cependant, ce n'est pas le cas, les opérations vectorielles ne s'appliquent pas à une liste. \n", "\n", "Il faut voir la liste comme une collection ordonnée de variables. Les variables peuvent avoir différents types. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "a = [1, 10.0, 'chat', [10, \"chien\"]]\n", "print(a[2])\n", "print(a[3][1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La liste regroupe ici des scalaires, des strings et une autre liste. Remarquez que contrairement à matlab, les indices commencent à 0, donc pour accéder au premier élément, on écrit `a[0]`. Remarquez aussi que pour accéder aux éléments d'une liste dans une liste, on doit utiliser une suite de crochets. Ainsi, `a[3]` nous retourne une liste de deux éléments, et donc `a[3][1]` nous retourne le deuxième élément de la liste `[10, \"chien\"]`.\n", "\n", "On peut directement itérer sur une liste:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "for el in a:\n", " print(el)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut aussi additionner deux listes, ce qui les met bout à bout." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "a = [1, 2]\n", "b = [3, 4]\n", "c = a + b\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les indices négatifs permettent d'obtenir un élément en commençant à la fin de la liste." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "a[-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il est souvent utile de sélectionner un sous-ensemble des éléments d'une liste, ce qu'on nomme slicing en anglais. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "a = [1,2,3,4]\n", "\n", "print(a[1:-1]) #Enlève le premier et dernier élément\n", "print(a[:-1]) #Enlève le dernier élément\n", "print(a[-1:1:-1]) #Par du dernier élément, et renverse la liste" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.7 Les dictionnaires\n", "\n", "Un dictionnaire est similaire à une liste, en ce qu'il regroupe plusieurs variables ensemble. Cependant, on accède aux différents éléments par un nom et non par l'ordre dans le regroupement." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "a = {\"chat\": 10, \"chien\": 20}\n", "print(a[\"chat\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La liste se définie avec les accolades `{}`, et chaque élément est définit comme `{nom: valeur}`. On récupère un champs avec les crochets `valeur = a[nom]`.\n", "\n", "Une fois la liste créée, on peut ajouter un champ directement avec les crochets." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "a[\"oiseau\"] = 30\n", "print(a[\"oiseau\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Attention! Les listes ne préservent pas l'ordre, mais peuvent aussi être utilisées dans des boucles. Dans l'exemple suivant, l'ordre de définition peut être respecté, ou pas.." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "for el in a:\n", " print(\"nom: %s, valeur %d\" % (el, a[el]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Les objets\n", "\n", "Vous n'aurez pas à définir des objets dans ce cours. Cependant, Pygmili, la librairie géophysique que nous utliserons dans les TP, est écrite avec des objets. Quelques notions sont ainsi nécessaires.\n", "\n", "Un objet regroupe des données (variables) et des fonctions (ou méthodes). Une classe est le gabarit qui permet de créer un objet, et plusieurs objets peuvent être créés d'une même classe. Voici un exemple." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "class exemple:\n", " \n", " def __init__(self, x):\n", " self.x = x\n", " \n", " def add(self, y):\n", " self.x = self.x + y\n", " return self.x\n", "\n", "a = exemple(2)\n", "b = exemple(2)\n", "a.add(1)\n", "print(a.x)\n", "print(b.x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Que se passe-t-il ici ?\n", "\n", "1. Premièrement, nous avons défini une classe `exemple` possédant deux méthodes (fonctions): `__init__` et `add`. \n", "2. La méthode `__init__` est particulière: elle est appelée par défaut lorsqu'on crée un nouvel objet à partir de cette classe. \n", "3. Lorsqu'on crée `a`, la classe appelle `__init__`, et assigne `2` à la variable `self.x`. \n", "4. La variable `self` à l'intérieur de la classe sert à désigner l'objet: toutes les méthodes d'une classe prennent comme premier argument `self`. Quand on crée deux objets différents avec la classe, chaque objet (`a` et `b`) par exemple possède une variable `self` distincte.\n", "5. On accède aux variables et méthodes d'un objet par un point, ainsi `a.x` retourne la valeur de x de l'objet a.\n", "6. Lorsqu'on exécute `a.add(1)`, nous voulons éxécuter la méthode `add` de la classe `exemple` à l'objet `a`, avec comme argument `y=1`. Ainsi, lorsqu'on appelle la méthode d'une classe, le premier argument `self` ne doit pas être inclus, il l'est par défaut. La fonction `add` ajoute à `a.x` `1`, puis retourne la valeur de `a.x`\n", "\n", "L'exemple ici est simple et plutôt inutile. Cependant, vous aurez à accéder à des variables et des fonctions provenant d'objets, donc vous saurez maintenant pourquoi on utilise les `.` en python." ] }, { "cell_type": "markdown", "metadata": { "nbpages": { "level": 3, "link": "[1.1.4.2 Python Libraries](https://jckantor.github.io/CBE30338/01.01-Getting-Started-with-Python-and-Jupyter-Notebooks.html#1.1.4.2-Python-Libraries)", "section": "1.1.4.2 Python Libraries" } }, "source": [ "## 3.0 Les librairies python\n", "\n", "Le langage python de base est plutôt limité. Ce qui nous intéresse est de faire du traitement de données et de la géophysique. Ces fonctionnalités se retrouvent à l'intérieur de librairies, qui peuvent être installées et importées facilement dans python.\n", "\n", "Habituellement, on importe les librairies requises au début d'un script ou d'un notebook. Pour importer la libraire Numpy, on écrit simplement:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpages": { "level": 3, "link": "[1.1.4.2 Python Libraries](https://jckantor.github.io/CBE30338/01.01-Getting-Started-with-Python-and-Jupyter-Notebooks.html#1.1.4.2-Python-Libraries)", "section": "1.1.4.2 Python Libraries" }, "scrolled": false }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ici, on importe la librairie numpy et on lui assigne le nom `np`. Pour appeler les fonctionnalités de numpy, il faudra utiliser ce nom, suivi d'un point et de la fonction désirée, comme pour un objet." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "print(np.max([1,2]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il est aussi possible d'importer directement des fonctions d'une librairie avec la sémantique suivante." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "from numpy import dot\n", "dot([1,2], [3,4])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ici, nous n'avons pas à indiquer `np.dot` car la fonction `dot` a directement été importée avec son nom. Pourquoi alors utiliser `np.fun` ? Imaginez que vous ayez deux fonctions `dot` dans deux librairies différentes et que vous importez ces deux librairies: vous ne pourrez utiliser les deux en même temps. Avec cette façon de faire, vous pouvez appeler ces deux fonctions sans ambiguïtés." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.1 Numpy\n", "\n", "La librairie numpy permet d'utiliser python pour du calcul scientifique et introduit la plupart des fonctions incluses dans Matlab.\n", "\n", "Ainsi, on peut créer des vecteurs à partir de listes avec la fonction `np.array`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "a = np.array([1,2,3])\n", "print(a.shape)\n", "print(a.max())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un array possède un objet qui possède plusieurs méthodes intéressantes, comme `np.array.shape` qui retrouve les dimensions de la matrice, `np.array.max` qui retourve la valeur maximale." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On crée de la même façon des matrices." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "b = np.array([[1,2,3], [4,5,6]])\n", "print(b.shape)\n", "print(b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On peut faire leur produit matriciel." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "np.dot(b,a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ici, contrairement à Matlab, les opérateurs `*` `\\` n'implémentent pas directement des opérations matricielles, mais effectuent ces opérations élément pas élément. Par exemple:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "a * a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Créer une suite de nombre est facile avec Numpy:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "a = np.arange(1, 10, 2) # suite de nombres de 1 à 10 avec un pas de 2\n", "print(a)\n", "b = np.linspace(1, 10, 4) # suite de nombres entre 1 et 10 avec 4 valeurs\n", "print(b)\n", "c = np.logspace(1, 3, 4, base=2) # séquence logarithmique entre 2**1 et 2**3 avec 4 valeurs\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Les fonctions mathématiques de base sont toutes accessibles avec Numpy. En voici quelques exemples." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "print(np.sum(a)) #effectue la somme de tous les éléments\n", "print(np.sin(a)) #calcule le sinus de tous les éléments\n", "print(np.exp(a)) #calcule l'exponentiel de tous les éléments" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Bref, la plupart des fonctions que vous connaissez dans Matlab sont accessibles dans Numpy, avec presque la même synthaxe." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Enfin, tout comme les listes, on peut découper un `np.array`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "b = np.array([[1,2,3], [4,5,6]])\n", "print(b)\n", "\n", "print(b[:, 1:-1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.2 Matplotlib\n", "\n", "Maitenant que vous pouvez faire du calcul scientifique en python, il faut présenter vos résultats avec des figures. Pour cela, la librairie Matplotlib est l'outil par excellence. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matplotlib fonctionne de façon similaire à Matlab. Voici un script simple qui crée une figure, avec des noms d'axe." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "#Création des données\n", "x = np.arange(0, 100)\n", "y1 = np.sin(2 * np.pi / 10 * x)\n", "y2 = np.cos(2 * np.pi / 10 * x)\n", "y3 = np.exp(-(x-50)**2/10**2)\n", "\n", "#Création des figures\n", "fig, axs = plt.subplots(2, 1, figsize=(10, 5))\n", "axs[0].plot(x, y1, \"-*\")\n", "axs[0].plot(x, y2, \"-o\")\n", "axs[0].set_title('Demonstration de figure')\n", "axs[0].legend(['Sin','Cos'])\n", "axs[0].set_xlabel(\"x\")\n", "axs[0].set_ylabel(\"y\")\n", "\n", "axs[1].plot(x, y3)\n", "axs[1].set_title('Un autre axe')\n", "axs[1].set_xlabel(\"x\")\n", "axs[1].set_ylabel(\"y\")\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "À noter qu'on utilise ici `plt.subplots` qui permet de créer une figure comportant plusieurs axes. Pour tracer plusieurs séries sur un même axe, il suffit d'appeler `ax.plot` plusieurs fois, comme démontré sur le premier axe. La fonction `plt.tight_layout()` permet d'ajuster la taille des axes pour bien paraître sur la figure (essayez sans). Enfin, la dernière fonction `plt.show()` est nécessaire pour afficher la figure créée, sans quoi, rien n'apparaîtra." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il est possible de créer une panoplie de types de figure avec Matplotlib. Un bon point de départ est le site de [Matplotlib](https://matplotlib.org/stable/gallery/index.html) où plusieurs exemples sont accessibles. Voici quelques types de figures qui vous seront utiles dans les travaux pratiques." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "x1 = np.random.rand(100)\n", "\n", "x2 = np.logspace(1, 4)\n", "y2 = np.logspace(1, 4)\n", "\n", "x3 = np.arange(100)\n", "y3 = np.exp(x3/100)\n", "\n", "x4, y4 = np.meshgrid(np.arange(100), np.arange(100))\n", "z4 = np.sin(2 * np.pi / 30 * x4)*np.sin(2 * np.pi / 50 * y4)\n", "\n", "fig, axs = plt.subplots(2, 2, figsize=(10, 5))\n", "axs[0, 0].hist(x1)\n", "axs[0, 1].loglog(x2, y2)\n", "axs[1, 0].semilogy(x3, y3)\n", "axs[1, 1].imshow(z4, extent=[0, 100, 0, 100])\n", "\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.0 Exercice\n", "\n", "Afin de mettre en pratique ce que nous venons de voir, voici un petit exercise sur des mesures de polarisation spontanée effectuées en 2018.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.1 Importation des données (0.5 pts)\n", "\n", "Dans un premier temps, importez le fichier de données dans un `np.array`. Les données de polarisation spontanée se trouvent dans le fichier `donnees_PS2018.csv` et celle de la topographie sont dans `topo.csv`. Vous pouvez voir ces fichiers dans l'explorateur de Jupyter (à partir duquel vous avez ouvert le présent notebook). On vous propose d'utiliser la fonction `np.genfromtxt`. Pour voir comment celle-ci fonctionne, vous pouvez tapper `help(np.genfromtxt)` dans la cellulle suivante ou faire une petite recherche google. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "#Répondre ici.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2 Formatage des données (0.5 pts)\n", "\n", "Créez une variable avec les noms `distance`, `mesures`, `temps`, et `topox` et `topoz` regroupant les colonnes correspondantes des variables que vous venez d'importer." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "#Répondre ici.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.3 Affichage des données (1 pts)\n", "\n", "Montrez sur un graphique le temps en fonction de la distance des mesures sur un premier axe, les mesures brutes en fonction de la distance sur un deuxième axe et la topographie en fonction de la distance sur un troisième axe. Assurez vous d'inclure un titre et les titres des axes." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "#Répondre ici.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.4 Correction des données (1 pts)\n", "\n", "Quelle est la valeur de la dérive ? " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Réponse : \n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Effectuez la correction de dérive, selon la formule suivante:\n", "\n", "\\begin{align}\n", "m_{corr} = m - \\Delta (t-t0)\n", "\\end{align}\n", " \n", " où $m_{corr}$ et $m$ sont les valeurs corrigées et non-corrigées, respectivement et $\\Delta$ est le taux de dérive, calculé comme:\n", " \n", "\\begin{align}\n", "\\Delta = \\frac{m_{base}(t=t_2) - m_{base}(t=t_1)}{t2 - t1}\n", "\\end{align}" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "#Répondre ici.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.5 Affichage des données traitées (1 pts)\n", "\n", "Mettre sur le même graphique les mesures corrigées et non corrigées, en incluant une légende. Prenez soin d'enlever tous doublons dans les mesures, par exemple, la station de base." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "#Répondre ici.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.6 Interprétation des données (1 pts)\n", "\n", "Est-ce que la topographie pourrait affecter les mesures PS dans ce cas ? Expliquez." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Réponse : \n", "\n", "" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" } }, "nbformat": 4, "nbformat_minor": 2 }