Python pour les noobs !

Ceci est le support de la formation Python interne à l’UMR LETG qui se déroulera sur une journée en 2023. Que vous connaissiez un peu Python ou pas du tout, cette formation est faite pour vous !

Préparer son environnement

Pré-requis : installation des logiciels

Assurez-vous d’avoir les logiciels suivants installés sur votre machine :

Si Python n’est pas déjà installé sur votre ordinateur, installez directement Miniconda ou Anaconda : Python sera installé en même temps !

Si Python est déjà installé sur votre ordinateur, vous pouvez tout de même installer Miniconda ou Anaconda, les 2 versions coexisteront. Ne désinstallez pas la version de Python déjà installée ! Si besoin référez-vous à la FAQ Anaconda > “I already have Python installed. Can I install Anaconda?”

Pour savoir si Python est installé ou non, référez-vous aux instructions ci-dessous : si un message d’erreur vous est renvoyé, Python n’est probablement pas installé.

Vous pouvez vérifier le bon fonctionnement de votre installation avec la procédure suivante :

  1. Ouvrir un terminal (PowerShell sous Windows) : appuyer sur la touche avec l’icône Windows de votre clavier, puis taper “PowerShell” et appuyer sur Entrée
  2. Dans le terminal : taper python --version puis appuyer sur Entrée
  3. Vous devriez voir s’afficher une ligne du type Python 3.X.Y ou 3.X.Y est le numéro de la version de Python installée sur votre machine.

Usage de base

Deux cas de figure sont possibles :

  1. Dans un terminal, taper python : l’interpréteur Python se lance et vous permet de taper et d’exécuter des commandes. Dans une terminal PowerShell sous Windows, il peut être nécessaire de remplacer python par py.

Pour fermer l’interpréteur : exit()

(conda_env) foo@bar:~$ python
Python 3.9.6 | packaged by conda-forge | (default, Jul  6 2021, 08:53:59) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello World!")
Hello World!
>>> exit()
(conda_env) foo@bar:~$
  1. Pour plus de praticité : écrire du code Python dans un fichier texte, avec l’extension .py, puis exécuter le programme avec la commande python mon_programme_python.py
(conda_env) foo@bar:~$ python mon_programme_python.py
(conda_env) foo@bar:~$

Pour pouvoir exécuter un script python de cette manière, il faut se placer dans le même répertoire que celui-ci. Dans un terminal, on utilise pour cela la commande cd pour “change directory”. Par exemple, si vous êtes dans votre dossier utilisateur (ce qui est le cas par défaut quand on ouvre un terminal), cd Desktop “descendra” dans le dossier nommé Desktop. La commande cd .. remonte d’un dossier.

Pour lister tous les éléments présents dans le dossier où vous vous trouvez, vous pouvez utiliser la commande ls, ou bien dir si vous utilisez un terminal conda (anaconda prompt).

Pour gagner du temps : après avoir tapé les premières lettres d’un nom de dossier, utilisez la touche tabulation pour la complétion automatique. Et utilisez la flèche du haut du clavier pour appeler les dernières commandes utilisées !

L’option 2 est à privilégier dès lors qu’il y a nécessité d’exécuter plusieurs fois un même programme, ou si celui-ci dépasse quelques lignes de code.

Les environnements virtuels

Il existe plusieurs versions de Python, et de nombreux modules supplémentaires. C’est une richesse, mais ça peut aussi être source d’ennuis si vous voulez que vos collègues puissent utiliser vos scripts, s’ils ne possèdent pas la même version de Python et de ses modules que vous !

Pour pallier ce problème, on peut utiliser des environnements virtuels : chaque environnement aura sa propre version de Python, et ses propres modules Python. Vous pouvez ainsi documenter les versions utilisées, et transmettre cet environnement à vos collègues.

L’utilisation d’environnements virtuels présente 2 avantages :

  • la reproductibilité de vos programmes (science ouverte) : l’environnement virtuel contient une photographie de la configuration utilisée
  • la gestion des dépendances : l’installation de multiples modules peut engendrer des conflits de version

Deux possibilités (les commandes doivent être tapées dans un terminal, ou dans un PowerShell sous Windows) :

  • avec Miniconda3/Anaconda :
    • conda create -n mon_environnement python=3.9 : créer un environnement avec une version de Python spécifique
    • conda env list : lister les environnements existants
    • conda activate mon_environnement : activer un environnement
    • conda install <package> : installation d’un paquet
    • conda deactivate : désactiver l’environnement
    • conda env remove --name mon_environnement pour supprimer l’environnement
  • sans Miniconda3, avec venv et pip :
    • python -m venv mon_environnement : création
    • source mon_environnement/bin/activate : activation sous Linux/MacOSX
    • mon_environnement/Scripts/activate.bat (invite de commande) ou mon_environnement/Scripts/Activate.ps1 (PowerShell) : activation sous Windows
    • pip install <package> : installation d’un paquet
    • deactivate : désactivation

Une fois l’environnement activé, les paquets/modules installés (conda install mon_paquet / pip install mon_paquet) le sont uniquement dans cet environnement. Pour installer/exporter une configuration (partage avec un collègue par exemple) :

  • exporter : conda env export > requirements.yml exporte l’environnement dans un fichier yaml (pip freeze > requirements.txt avec venv et pip).
  • installer : conda env create -f requirements.yml / pip install -r requirements.txt installe les paquets présents dans le fichier de dépendances au sein de l’environnement actif.

Application : création d’un environnement

Nous allons commencer par créer un environnement virtuel pour cette formation, nommé atelier. Tous les modules Python installés seront installés dans cet environnement, que vous pourrez décider de supprimer plus tard si vous le souhaitez !

Toutes les commandes utilisées ici ne sont pas des commandes Python, il faut les taper dans un terminal ou dans un PowerShell Windows.

Si Anaconda ou Miniconda est installé sur votre ordinateur (recommandé) :

Pour créer un environnement nommé atelier :

conda create --name atelier python

Vous pouvez maintenant voir cet environnement dans la liste de vos environnements virtuels :

conda env list

Pour activer cet environnement :

conda activate atelier

Pour revenir à l’environnement de base, vous pouvez utiliser la commande conda activate.

Vous pouvez maintenant installer des modules Python dans cet environnement (l’équivalent des packages R), par exemple matplotlib qui nous servira à faire des graphiques :

conda install matplotlib

On peut voir la liste des modules installés dans un environnement avec cette commande :

conda list -n atelier

Si conda n’est pas installé sur votre ordinateur :

Pour créer un environnement nommé atelier :

python -m venv atelier

Pour l’activer sous Windows (il faut être dans le répertoire où est situé l’environnement) :

# dans l'invite de commandes : 
cd atelier/Scripts
activate.bat
# dans powershell : 
cd atelier/Scripts
Activate.ps1

Sous VisualStudio, si vous obtenez une erreur vous indiquant que l’exécution de scripts est désactivée, vous pouvez changer le type de terminal de PowerShell vers cmd comme indiqué ici.

Pour l’activer sous Linux ou MacOSX :

source atelier/bin/activate

Installation de modules dans cet environnement

Pour installer les module qui seront utilisés durant la formation dans cet environnement : il faut d’abord vérifier que l’environnement soit bien activé, vous devez voir (atelier) au début de la ligne de commande.

Vous pouvez ensuite installer des modules dans cet environnement avec la commande pip install ou conda install. Par exemple pour installer tous les modules qui seront utilisés lors de cette formation :

pip install pandas
pip install numpy
pip install plotly
pip install kaleido
pip install geopandas
pip install matplotlib
pip install rasterio
pip install earthpy

Les commandes pour installer des modules Python ne sont pas des commandes Python ! Il faut donc les lancer dans un terminal ou équivalent.

3 autres modules seront nécessaires, mais font normalement partie de l’installation Python de base : glob, os et shutil.

Bravo, vous êtes parés pour la suite !

Première rencontre avec un python

Présentation générale

Python est un langage de programmation (comme C, C++ ou Java) : un ensemble de termes et de règles permettant de créer des instructions.

Il peut être utilisé dans de nombreux domaines :

  • calculatrice avancée : manipulation de nombres, calcul scientifique
  • scripts (traitement par lot de fichiers, communication avec des APIs, domotique, webscraping)
  • développement logiciel : création de sites web, APIs, gestion de bases de données, etc.
  • science des données : apprentissage automatique, visualisation de données, etc.
  • et plein d’autres choses encore…

Quelques particularités :

  • langage interprété : pas de compilation manuelle du code (comme le make en C)
  • indentation : permet d’améliorer la lisibilité du code (moins de symboles)
  • typage dynamique : pas besoin de préciser le type de vos variables (mais ça reste possible !)

Syntaxe générale

  • Pour commenter une ligne : #
  • Pour importer un module (plus de détail sur la définition d’un module ici : https://docs.python.org/fr/3/tutorial/modules.html):
    • import mon_module
    • import mon_module_trop_trop_long as ml pour utiliser un alias
    • from mon_module import sous_module ou import mon_module.sous_module pour importer un sous-module
    • from mon_module import fonction1, fonction2 pour importer directement des fonctions précises
  • Créer une variable (i.e. assigner une valeur ou un objet à un nom) :
    • ma_variable = 1
    • ma_variable = 'test'
    • ma_variable = [0, 2, 4]
    • ma_variable = ma_variable_1
  • L’interpréteur est sensible à la casse : ma_variableMA_VARIABLE
  • Appeler une fonction : ma_fonction(ma_variable_1, ma_variable_2)
  • Tests logiques :
    • ma_variable == 1, ma_variable >= 1, ma_variable != 'foo'
    • a = True, b = False, a or b, a and b, a, not b
    • valeur in [1, 'foo', 3.14]

Indentation :

  • l’indentation est utilisée pour délimiter des blocs de code (fonctions, boucles, classes, etc.)
  • l’indentation peut se faire au moyen d’espaces ou de tabulations. La PEP8 privilégie l’utilisation des espaces (4).
# blocs de code
ma_variable = 0
for i in range(4):
    ma_variable += 1

if ma_variable == 4:
    print('OK')
else:
    print('NOK')
## OK

Bref focus sur les éditeurs pour Python

Comme nous l’avons vu plus haut, on peu taper des commandes python directement dans un terminal, ou bien utiliser un éditeur spécialisé comme VSCode ou Spyder. Nous vous recommandons un de ces 2 derniers pour cette formation.

Dans l’un ou l’autre de ces logiciels, vous aurez accès à :

  • une console Python pour taper des commandes une à une (pour tester une commande par exemple)
  • un éditeur de texte pour créer et éditer des fichiers .py. Vous pourrez soit exécuter tout le fichier et donc lancer toutes les commandes, soit exécuter les commandes ligne par ligne, pour les tester ou débugger par exemple
  • d’autres panneaux, par exemple un explorateur de fichiers, un explorateur de variables, une aide…

Spyder est un éditeur spécifique pour Python, tandis que VSCode est plus versatile et fonctionne pour de nombreux langages.

Vous pouvez donc utiliser l’un ou l’autre pour taper les commandes ci-dessous !

Variables

Les variables sont la nourriture favorite des pythons ! Mais qu’est-ce qu’une variable ? C’est simplement un objet ou une valeur auquel on donne un nom, pour pouvoir l’appeler plus facilement.

Par exemple, on peut créer une variable nommée jour à laquelle on donne la valeur ‘jeudi’ :

jour = 'jeudi'

Notez que le nom d’une variable (jour) ne sera jamais entre guillemets ! Sa valeur (‘jeudi’) est entre guillemets car il s’agit d’une chaîne de caractères. Vous pouvez utiliser indifféremment les guillemets simples ou doubles !

jour = "jeudi"

Si on tape le nom de cette variable, sa valeur est renvoyée :

jour
## 'jeudi'

Une variable peut contenir tout type d’objet : chaîne de caractères (string) comme ici, nombre, liste de valeurs, dictionnaire… A noter, le langage Python n’est pas typé : une même variable pourra changer de type.

jour = 4
jour
## 4

Types de variables simples : chaîne de caractères et nombres

Chaîne de caractères ou string

Comme nous venons de le voir, une chaîne de caractères sera indifféremment entre guillemets simples ou doubles.

On peut additionner 2 chaînes de caractères :

"aujourd'hui on est " + "jeudi"
## "aujourd'hui on est jeudi"

et même les multiplier !

'---' * 10
## '------------------------------'

Comme une liste (voir un peu plus bas), une chaîne de caractères est indexable, chacun de ses caractères ayant un index :

langage = 'python'
langage[0]
## 'p'
langage[2:6] # attention, le dernier index n'est pas inclus !
## 'thon'

En Python, comme dans beaucoup d’autres langages (mais contrairement à R !), on commence à compter à zéro. Ce qui veut dire que le 1er élément aura un indice de 0, le 2ème un indice de 1, etc.

Il existe différentes fonctions pour manipuler des chaînes de caractères, par exemple pour passer en majuscules :

langage = 'python'
langage.upper()
## 'PYTHON'

Nombres

On peut également utiliser python pour manipuler des nombres :

2 + 2 # les espaces servent uniquement pour la lisibilité, ils sont facultatifs
## 4

On n’utilise pas de guillemets pour les nombres :

nombre = 4

Toutes les opérations usuelles sont possibles.

nombre**2
## 16

Les nombres peuvent être entiers (integer) ou décimaux (float) :

nb = 4
type(nb)
## <class 'int'>
nb = 4.2
type(nb)
## <class 'float'>

On peut aussi utiliser la notation scientifique, dans ce cas le nombre sera toujours de type float :

nb = 1e6
nb
## 1000000.0
type(nb)
## <class 'float'>

Et si on met un nombre entre guillemets ? Il devient une chaîne de caractères !

10 > 4
## True
'10' > '4' # les chaînes de caractères sont classées dans l'ordre alphabétique
## False

Nous allons maintenant voir quelques types de variables plus complexes qui vous seront utiles !

Structures de données

Listes

Une liste est un ensemble de valeurs ordonnées. Chaque valeur peut être une variable de n’importe quel type : chaîne de caractères, nombre, liste… Chaque valeur d’une même liste peut être de type différent, même si habituellement toutes les valeurs auront le même type.

  • [0, 1, 2], ['orange', 'banane', 'ananas'], [[0, 1, 2], [3, 4, 5], [2, 1, 0]]
  • Voir la longueur d’une liste : len(ma_liste)
  • Accéder à un élément : ma_liste[0], ma_liste[-1]
  • Accéder à plusieurs éléments consécutifs : ma_liste[2:5] pour accéder aux éléments d’index 2, 3 et 4 par exemple
  • Ajouter un élément : ma_liste.append(3), ma_liste.insert(3, 'pomme')
  • Supprimer un élément : ma_liste.remove('pomme'), ou bien selon son index : ma_liste.pop(2)
  • Trier une liste : sorted(ma_liste), ma_liste.sort(reverse=False)
  • Créer une liste : ma_liste = range(4), ma_liste = [x**2 for x in range(4)]
  • Listes particulières : tuples (immutable) et sets (liste sans doublon)

Important: le premier élément d’une liste a l’indice 0 !

Exercices d’application sur les listes

Voici quelques petits exercices pour s’entraîner à manipuler des listes :

villes = ['Nantes', 'Rennes', 'Brest']

Comment faire pour renvoyer la première valeur de la liste ?

villes[0]

Et pour renvoyer la dernière valeur de la liste ? (2 possibilités !)

villes[2] # renvoie la 3ème valeur
## 'Brest'
villes[-1] # renvoie la dernière valeur
## 'Brest'

Ajoutez un élément ‘Nouméa’ à la fin de la liste :

villes.append('Nouméa')
villes # pour voir le résultat

Classez maintenant cette liste par ordre alphabétique (voyez-vous la différence entre sorted(villes) et villes.sort() ?) :

sorted(villes)
villes # la liste n'a pas été modifiée
villes.sort()
villes # la liste a été modifiée

Remplacez l’élément ‘Nouméa’ par ‘Dublin’ :

villes[2] = 'Dublin' # si la liste a été classée, Nouméa est le 3ème élément de la liste (indice 2)
villes

Supprimez l’élément ‘Dublin’. Vous pouvez pour cela vous baser sur son nom, ou sur sa position dans la liste.

# en appelant l'élément par sa valeur
villes.remove('Dublin')
villes
# on réinitialise la liste
villes = ['Brest', 'Nantes', 'Dublin', 'Rennes']
# en appelant l'élément par son index
villes.pop(2) # cette fonction renvoie la valeur supprimée
villes

Si vous voulez plus d’exercices sur les listes, rendez-vous ici !

Dictionnaires

Un dictionnaire est un ensemble d’éléments de type clé:valeur. Les valeurs peuvent être de n’importe quel type : chaîne de caractère, nombre, liste, et même dictionnaire !

Il n’y a pas de notion d’ordre dans un dictionnaire : on accède à un élément par sa clé et non par son index, contrairement aux listes.

  • {0: 'pomme', 1: 'banane'}, {'id1': 20, 'id2': 40}, {1: {'id': 3, 'nom': 'Dupont'}, 2: {'id': 4, 'nom': 'Durand'}}
  • Accéder à un élément : mon_dict['cle']
  • Liste des clés : mon_dict.keys(), list(mon_dict)
  • Ajouter un élément : mon_dict['nouvel élement'] = valeur
  • Supprimer un élément : del(mon_dict['cle'])
  • Parcourir l’ensemble des éléments : for key, value in mon_dict.items()
  • Vérifier l’existence d’une clé : 'cle' in mon_dict

Exercices d’application pour s’entraîner à manipuler les dictionnaires

pause = {'chouquettes' : 25, 'croissants' : 12, 'pains au chocolat' : 12}

Affichez le nombre de chouquettes prévues pour la pause :

pause['chouquettes']

Ajoutez un élément ‘cafés’ avec la valeur 15 dans ce dictionnaire :

pause['cafés'] = 15
pause

Afficher la liste des types de nourriture ou boisson prévues (liste des clés) :

pause.keys()

Tous les pains au chocolat ont été mangés, mettez le dictionnaire à jour en supprimant cet élément :

del(pause['pains au chocolat'])
pause

Et il ne reste plus que 3 cafés, mettez également le dictionnaire à jour :

pause['cafés'] = 3
pause

On peut afficher le nombre d’éléments de cette manière par exemple :

print('Actuellement, il reste : ')
for key, value in pause.items():
  print (value, key)

Si vous voulez plus d’exercices sur les dictionnaires, rendez-vous ici !

Structures de contrôle

Structure conditionnelle : if, elif, else

a = 12
if a == 0:
    print("Nul !")
elif a < 10:
    print("À revoir")
elif a < 15 and a >= 10:
    print("Correct")
else:
    print("Très bien")
## Correct

À retenir :

  • les : à la fin des conditions
  • l’indentation pour chaque bloc conditionnel
  • les conditions elif et else ne sont pas obligatoires

Structure itérative : for

Syntaxe générique : for item in iterable

Un iterable en Python est un objet dont on peut parcourir les valeurs, exemple : str, tuple, list, dict et set.

Exemple :

villes = ['Nantes', 'Rennes', 'Brest']
for ville in villes:
    print (ville)
## Nantes
## Rennes
## Brest

Dans l’exemple ci-dessus, ville va prendre successivement toutes les valeurs de la liste villes. La boucle for sera donc parcourue 3 fois.

Autre cas : la boucle while

Syntaxe générique :

while condition is not False:
    # Exécution du code qui suit

Exemple :

i = 0
while i < 10:
    i = i + 1
    print(i)
## 1
## 2
## 3
## 4
## 5
## 6
## 7
## 8
## 9
## 10

Attention : si la condition d’arrêt n’est pas précisée ou mal écrite, le programme entre dans une boucle sans fin !

Exercices d’application sur les structures de contrôle

pause = {'chouquettes' : 25, 'croissants' : 12, 'pains au chocolat' : 12}

Utilisez une boucle if/else qui indique s’il y a plus de croissants, plus de pains au chocolat, ou bien autant de chaque :

if pause['croissants'] > pause['pains au chocolat']:
    print ('plus de croissants que de pains au choc')
elif pause['pains au chocolat'] > pause['croissants']:
    print ('plus de pains au choc que de croissants')
else:
    print ('autant de chaque !')

10 personnes ont chacune mangé une chouquette, un croissant et un pain au chocolat. Mettez à jour le dictionnaire en utilisant une boucle for pour enlever 10 à chacune des valeurs.

for key, value in pause.items():
  pause[key] = value - 10
pause

On crée une nouvelle variable participants (et on réinitialise pause) :

pause = {'chouquettes' : 25, 'cafés' : 15}
participants = ['Alice', 'Bob', 'Carole']

Chacun des participants mange 2 chouquettes et boit un café. Mettez à jour le dictionnaire pause grâce à une boucle for sur la liste participants.

for i in participants:
  #print (i) # décommentez pour afficher i
  pause['chouquettes'] = pause['chouquettes'] - 2
  pause['cafés'] = pause['cafés'] - 1
pause

Utilisez une boucle while pour enlever 1 au nombre de cafés, jusqu’à ce que ce nombre arrive à 0, en affichant à chaque fois le nombre de cafés restant. Quand ce nombre tombe à 0 (= en sortant de la boucle), affichez un message indiquant qu’il ne reste plus de café.

while pause['cafés'] > 0:
  print ('Il reste ' + str(pause['cafés']) + ' café(s)')
  pause['cafés'] = pause['cafés'] - 1
print ('Désolé, plus de café !')

Erreurs

Si l’interpréteur observe une erreur de syntaxe ou un problème quelconque dans l’exécution du code, il lève une exception. Quelques exemples :

  • SyntaxError: invalid syntax
  • FileNotFoundError: [Errno 2] No such file or directory: 'mes_donnees.csv'
  • ZeroDivisionError: division by zero
  File "<stdin>", line 1
    if True print('Hello world')
                ^
SyntaxError: invalid syntax

Pour aller plus loin :

On peut gérer les erreurs avec try/except.

Par exemple, si une clé n’existe pas dans un dictionnaire, on obtient une erreur de type KeyError :

pause['thé']

Pour mieux gérer ce type d’erreur :

cle = 'thé'
try:
    pause[cle]
    print ('oui, il y a bien du ' + cle)
except KeyError:
    print ('désolé, pas de ' + cle)

Modules utiles

Un module Python est un fichier contenant un ensemble de définitions (fonctions, classes) que vous pouvez importer dans votre propre programme. Vous pouvez créer vos propres modules, ou bien utiliser des modules provenant de la communauté (organisés en paquets).

Voici quelques modules fréquemment utiles:

  • sys et os pour interagir avec l’interpréteur et le système d’exploitation
  • glob pour parcourir des dossiers et lister des fichiers
  • math pour des fonctions mathématiques (cos(), sqrt(), pi)
  • datetime pour la manipulation de dates, timestamps, etc

Pour manipuler des données :

  • csv, json pour manipuler des fichiers excel ou json
  • pandas pour manipuler des données tabulaires
  • matplotlib, seaborn, plotly (et beaucoup d’autres) pour créer des graphiques
# avec un graphique basique
import matplotlib.pyplot as plt
x = [1, 2, 3]
y = [2, 4, 1]
plt.plot(x, y)

Science des données :

  • numpy : calcul numérique, manipulation de matrices
  • scipy : calcul scientifique (traitement du signal, statistiques, analyse numérique, etc.)
  • scikit-learn : machine learning

Pour la suite de la formation, vous aurez besoin des modules suivants (ils sont déjà installés normalement, vous n’avez plus qu’à les importer) :

import pandas as pd
import numpy as np
import os
import shutil
import plotly.express as px
import plotly.io as pio

Attention, plotly s’installe avec conda install plotly ou pip install plotly. On ne peut pas installer uniquement un sous-module de plotly.

Comment faire pour changer d’environnement virtuel dans un éditeur de code ?

Pour Spyder :

  • activer l’environnement dans lequel on veut travailler : conda activate myenv
  • installer le module spyder-kernels dans cet environnement : conda install spyder-kernels
  • récupérer le chemin vers l’interpréteur python de cet environnement : python -c "import sys; print(sys.executable)" et le copier (ce sera par exemple /home/pierson/miniconda3/envs/myenv/bin/python)
  • dans Spyder : menu Outils > Préférences > Interpréteur Python, choisir Utiliser l’interpréteur suivant et coller le chemin (par la suite, il sera disponible dans la liste déroulante)
  • lancer une nouvelle console (il suffit de fermer la console ouverte) : le nom de l’environnement en cours est lisible dans la barre de statut en bas de la fenêtre Spyder
  • si ça ne marche pas : éventuellement suivre les recommandations de spyder pour la version de spyder-kernels à installer, par ex. conda install spyder-kernels=2.3

Pour VSCode : je te laisse compléter si besoin Benjamin, voire supprimer cette partie si tu trouve que ça ajoute trop d’infos ;-)

Bonnes pratiques !

  • Privilégier l’encodage UTF-8 pour vos scripts/programmes
  • Documenter votre code (pour vous et pour les autres) : commentaires, métadonnées, README
  • Afficher les étapes intermédiaires (print(), logging) pour faciliter le déboggage
  • PEP8, conventions pour l’écriture de code Python : https://peps.python.org/pep-0008/

Chercher des informations et/ou de l’aide :

  • Dans Python, pour de l’aide sur une fonction ou un module : help(print)
  • …et pour obtenir de l’aide sur une méthode : help('a'.upper) (en savoir plus sur la différence entre fonction et méthode)
  • Le web est ton ami : trouver un paquet/module adapté, chercher de la documentation
  • StackOverflow : formuler son problème, fournir un exemple

Manipulation de données tabulaires avec le module pandas

Tutoriel pour l’utilisation de Pandas : https://www.kaggle.com/learn/pandas

Présentation

Import

Le module pandas est habituellement importé ainsi :

import pandas as pd

Introduction

Pandas repose sur la manipulation de tableaux et listes appelés DataFrame ou Series.

Exemple :

import pandas as pd
df = pd.DataFrame({'nom': ['Bob', 'Alice', 'Paul', 'Sarah', 'Junior'], 
                    'age': [24, 32, 40, 26, 16], 
                    'sexe': ['M', 'F', 'M', 'F', 'M']})
df.head()
##       nom  age sexe
## 0     Bob   24    M
## 1   Alice   32    F
## 2    Paul   40    M
## 3   Sarah   26    F
## 4  Junior   16    M

On peut obtenir le nombre de lignes avec :

df.shape[0] 
# ou encore :
## 5
len(df)
## 5

Et le nombre de colonnes :

df.shape[1]
## 3

Accéder aux valeurs

Par nom de colonne:

  • df.nom ou df['nom'] : renvoie un objet de type Series

Par numéro de ligne/colonne:

  • df.iloc[0] : renvoie la première ligne
  • df.iloc[:, 0] : toutes les lignes, première colonne

Par indice:

  • df.loc[0, 'age'] : renvoie la valeur age de la première ligne

Sélection conditionnelle : df.loc[df.age >= 30]

Focus sur les méthodes iloc et loc :

ILOC permet la sélection par numéro de ligne et de colonne, en spécifiant les lignes en 1er argument et les colonnes en 2ème argument : df.iloc[num ligne(s), num colonne(s)]

  • : renvoie toutes les lignes ou toutes les colonnes
  • on peut n’indiquer que le numéro de la ligne, dans ce cas toutes les colonnes seront renvoyées : df.iloc[2] (équivalent à df.iloc[2, :])
  • pour renvoyer toutes les lignes pour une colonne précise : df.iloc[:, 3]
  • au lieu de spécifier une ligne ou une colonne, on peut spécifier une plage, par exemple pour renvoyer les lignes 1, 2 et 3 : df.iloc[[0:3]]
  • ou bien appeler les lignes/colonnes une à une, ici pour renvoyer les colonnes 1, 3 et 5 : df.iloc[:, [0, 2, 4]]

LOC permet la sélection par nom de ligne ou de colonne : df.loc[nom ligne(s), nom colonne(s)], ainsi que la sélection conditionnelle : df.loc[condition sur les lignes, condition sur les colonnes] (les 2 types de sélection pouvant être combinés)

  • df.loc[:, 'nom'] renvoie la colonne nommée nom
  • si le dataframe ne possède pas de colonne d’index (équivalent aux en-têtes de colonnes mais pour les lignes), l’appel des lignes se fait par leur numéro : df.loc[0] renvoie la 1ère ligne (et est donc équivalent à df.iloc[0])
  • pour sélectionner par exemple selon une condition sur l’âge : df.loc[df.age > 20, :] (la condition s’applique bien sur les lignes et constitue donc le 1er argument, en 2ème argument on trouve ici : pour renvoyer toutes les colonnes (facultatif))

Tri

df.sort_values(by='age', ascending=False)
##       nom  age sexe
## 2    Paul   40    M
## 1   Alice   32    F
## 3   Sarah   26    F
## 0     Bob   24    M
## 4  Junior   16    M
df.sort_values(by=['age', 'nom'])
##       nom  age sexe
## 4  Junior   16    M
## 0     Bob   24    M
## 3   Sarah   26    F
## 1   Alice   32    F
## 2    Paul   40    M

Créer des valeurs

Création d’une nouvelle colonne :

df['majeur'] = True # toutes les lignes auront la même valeur
print (df)
##       nom  age sexe  majeur
## 0     Bob   24    M    True
## 1   Alice   32    F    True
## 2    Paul   40    M    True
## 3   Sarah   26    F    True
## 4  Junior   16    M    True

Création d’une colonne basée sur une condition :

# 2 méthodes :
df['majeur'] = np.where(df['age'] > 18, True, False)
df['majeur'] = df.apply(lambda row: row.age > 18, axis=1)

La fonction where du module numpy prend 3 arguments :

  • une condition, ici df['age'] > 18
  • et 2 valeurs, ici True et False La fonction est appliquée à chaque ligne : si la condition est vérifiée, la 1ère valeur est retournée, sinon, la deuxième valeur est retournée.

La fonction apply du module pandas applique une fonction à toutes les lignes (avec axis = 1) ou bien à toutes les colonnes (avec axis = 0) d’un dataframe. Il s’agit ici d’une fonction lambda.

Ici, la fonction renvoie le résultat de row.age > 18, row étant l’argument en entrée de la fonction, à savoir une ligne du dataframe puisque axis = 1. Pour chaque ligne, la fonction est appliquée et retourne donc True ou False.

Opération d’aggrégation

  • Nombre de femmes et d’hommes dans l’échantillon :
df.groupby('sexe')['nom'].count()
## sexe
## F    2
## M    3
## Name: nom, dtype: int64
  • Âge minimal :
df.groupby('sexe')['age'].min()
## sexe
## F    26
## M    16
## Name: age, dtype: int64

Lire/Écrire des fichiers

Lire un fichier CSV :

data = pd.read_csv("mon_fichier.csv") 

Le séparateur par défaut est la virgule, sinon il faut le préciser avec l’argument sep : pd.read_csv("mon_fichier.csv", sep = ';') par exemple.

Écrire dans un fichier CSV :

df.to_csv("mes_resultats.csv")

Exercice d’application 1 : avec un dataframe simple

pizzas = pd.DataFrame({'nom': ['margarita', '4 saisons', 'napolitaine'], 'nb ingrédients': [1, 4, 5], 'prix': [8, 12, 10]})
pizzas
##            nom  nb ingrédients  prix
## 0    margarita               1     8
## 1    4 saisons               4    12
## 2  napolitaine               5    10

Affichez la colonne prix (en l’appelant par son nom) :

pizzas['prix']
# ou bien : pizzas.prix

Affichez la première colonne (en l’appelant par sa position) :

pizzas.iloc[:, 0]

Affichez la deuxième ligne du tableau :

pizzas.iloc[1]

Affichez le prix d’une pizza napolitaine :

pizzas.loc[pizzas['nom'] == 'napolitaine', 'prix']

Affichez toutes les lignes des pizzas dont le prix est inférieur à 11€ :

pizzas.loc[pizzas['prix'] < 11]

Classez les lignes du tableau par prix croissant :

pizzas.sort_values(by = 'prix')

Exercice d’application 2 : à partir d’un CSV

Pour cet exercice, nous utiliserons un fichier sur le prix des carburants en France au 6 février 2023, téléchargé sur data.economie.gouv

Vous pouvez télécharger le fichier ici (ou bien directement sur le site data.economie.gouv, dans ce cas vous aurez une version plus à jour et des résultats légèrement différents).

Pour chaque question, il existe plusieurs réponses possibles. N’hésitez pas à consulter l’aide Python, ou bien à faire une recherche internet si vous êtes bloqué-e !

Pour lire ce fichier dans un dataframe :

# par défaut, le séparateur est la virgule, ici c'est un point-virgule, il faut donc le spécifier
# il faut aussi adapter le chemin vers le CSV !
carb = pd.read_csv('../Exo_dataframe/prix-carburants-2023-02-06.csv', sep = ';')

Pour voir les noms de colonnes (il y a d’autres méthodes !) :

carb.keys()
# ou de manière plus lisible :
for key in carb.keys():
  print (key)

Et pour voir le nombre de lignes :

len(carb)

Pour voir les valeurs manquantes :

# isna indique pour chaque valeur si elle est manquante (True) ou non (False)
carb.isna()
# c'est plus utile en regardant par exemple le nombre de valeurs manquantes par colonne
carb.isna().sum()

Pour voir les valeurs uniques dans une colonne, par exemple Automate 24-24 (oui/non), avec la méthode unique() :

carb['Automate 24-24 (oui/non)'].unique()
# Ou de manière un peu plus lisible :
for val in carb['Automate 24-24 (oui/non)'].unique():
  print (val)

On peut également compter les occurrences de chaque valeur unique avec value_counts() :

carb['Automate 24-24 (oui/non)'].value_counts()

Pour voir les prix par ordre croissant, en ne gardant que les colonnes commune et département :

carb.loc[:, ['Nom Officiel Commune', 'Nom Officiel Département', 'prix_valeur']].sort_values(by = 'prix_valeur')

En filtrant par code département pour ne garder que les résultats dans le Finistère :

carb.loc[carb['Code Officiel Département'] == '29', ['Nom Officiel Commune', 'Nom Officiel Département', 'prix_valeur']].sort_values(by = 'prix_valeur')

Pour afficher le prix moyen par département :

carb.groupby('Nom Officiel Département')['prix_valeur'].mean()

En classant du moins cher au plus cher :

carb.groupby('Nom Officiel Département')['prix_valeur'].mean().sort_values(ascending = True)

Un script reprenant toutes les commandes vues dans cet exercice est disponible ici.

Premier cas d’application

Option 1 : manipuler des fichiers

Principe

L’idée est ici de gagner du temps en automatisant une tâche, à savoir copier-coller des fichiers situés dans des répertoires différents vers un même dossier.

L’exemple portera sur des données LITTO3D en libre accès : en effet, quand on télécharge ces données, on obtient un dossier par dalle, et au sein de chacun de ces dossiers un dossier par sous-dalle, puis encore un dossier par type de produit :

Arborescence de dalles LITTO3D

Il est donc fastidieux d’aller ouvrir tous ces dossiers pour en extraire les images de la zone étudiée.

Nous vous proposons donc de télécharger quelques dalles LITTO3D, puis de faire un premier script Python avec en paramètres d’entrée :

  • un dossier de départ (dossier contenant toutes les dalles)
  • une liste de noms de dalles (ex. [‘0250_8130’, ‘0255_8130’])
  • un type de produit en sortie (ex. MNT)

et en sortie :

  • un dossier vide qui contiendra la résultat

Le script copiera dans le dossier en sortie toutes les sous-dalles du produit choisi.

Téléchargement des données

Les données peuvent être téléchargées sur diffusion.shom.fr.

Sélectionnez 2 ou 3 dalles (ou plus !) sur la zone de votre choix. Pour que les données ne soient pas trop lourdes à télécharger, sélectionnez des dalles en bordure de zone, par exemple sur les îles Éparses :

  • dalle 0255_8130
  • dalle 0260_8130
  • dalle 0250_8130

Exemple de téléchargement de 3 dalles légères sur les îles Éparses

Dézippez ensuite chacun des fichiers 7z, par exemple au moyen de 7zip.

Vous êtes prêt-e !

Script simple de copie des fichiers

Pour ce projet, vous aurez peut-être besoin :

  • de boucles for, puiqu’il va falloir itérer sur des dossiers contenus dans des dossiers
  • du module os pour manipuler des chemins et des noms de fichiers, notamment par exemple :
    • os.listdir pour lister le contenu d’un dossier
    • os.path.join pour créer un chemin en joignant par exemple un chemin absolu et un nom de dossier
    • os.path.isdir et os.path.isfile pour vérifier si un chemin correspond à un dossier ou un fichier
  • du module shutil pour copier un fichier, et notamment de la fonction shutil.copy2

Mais il existe beaucoup de possibilités, vous pouvez aussi utiliser par exemple le module pathlib !

Si vous ne savez pas trop par où commencer, procédez en plusieurs étapes :

  1. Créer un script qui liste (avec un print) tous les dossiers (dalles) contenus dans le dossier de départ
# paramètre en entrée : dossier de départ (A ADAPTER !!)
input_folder = '/home/pierson/Travail/donnees_SIG/LITTO3D/Iles_Eparses'
# pour chacun des éléments contenus dans le dossier de départ
for tile in os.listdir(input_folder):
  # affiche le nom de l'élément (le dernier "bout" du chemin)
  print ('dalle : ' + tile)
  1. Même chose, en ne gardant que les dalles dont le nom est contenu dans une liste
# paramètre en entrée : dossier de départ
input_folder = '/home/pierson/Travail/donnees_SIG/LITTO3D/Iles_Eparses'
# paramètre en entrée : liste de dalles
tile_list = ['0250_8130', '0260_8130']
# pour chacun des éléments contenus dans le dossier de départ
for tile in os.listdir(input_folder):
  # s'il s'agit bien d'une dalle de la sélection
  if tile in tile_list:
    # affiche le nom de l'élément (le dernier "bout" du chemin)
    print ('dalle : ' + tile)
  1. Puis en listant également tous les dossiers contenus dans chacun des sous-dossiers
# paramètre en entrée : dossier de départ
input_folder = '/home/pierson/Travail/donnees_SIG/LITTO3D/Iles_Eparses'
# paramètre en entrée : liste de dalles
tile_list = ['0250_8130', '0260_8130']
# pour chacun des éléments contenus dans le dossier de départ
for tile in os.listdir(input_folder):
  # s'il s'agit bien d'une dalle de la sélection
  if tile in tile_list:
    # chemin complet vers la dalle
    path_tile = os.path.join(input_folder, tile)
    # affiche le nom de l'élément (le dernier "bout" du chemin)
    print ('dalle : ' + tile)
    # pour chaque sous-dalle = sous-dossier
    for subtile in os.listdir(path_tile):
      # chemin complet vers la sous-dalle
      path_subtile = os.path.join(path_tile, subtile)
      # pour ne pas itérer sur les fichiers
      if os.path.isdir(path_subtile):
        print ('sous-dalle : ' + subtile)
  1. Et ainsi de suite… N’hésitez pas à tester les commandes dans la console, lire la documentation, faire des recherches internet, et demander de l’aide :-)

Un exemple de script complet est proposé ici. Il existe beaucoup d’autres manières de faire !

Pour aller plus loin

Et si on veut pouvoir spécifier en entrée, au lieu d’une liste de dalles, 4 coordonnées Nord, Sud, Ouest et Est formant un rectangle d’emprise ?

Les noms des dalles et sous-dalles, ainsi que ceux des fichiers, contiennent les coordonnées (en milliers) du point Nord-Ouest de la dalle ou sous-dalle, dans le système de coordonnées des images, par exemple :

arborescence d’une dalle litto3d avec une seule sous-dalle, les parties des noms de dalle, sous-dalle et fichier ASC correspondant aux coordonnées sont entourées en rouge

  • 0250_8130 correspond au point nord-ouest de l’emprise de la dalle
  • 0251_8126 correspond au point nord-ouest de l’emprise de la sous-dalle, et donc aussi du fichier MNT
  • le tout dans le système de coordonnées WGS84 / UTM 38S, comme indiqué dans le nom de sous-dalle et de fichier (puisqu’il s’agit ici des îles Éparses)

Tout ça sachant que :

  • les coordonnées réelles sont par exemple (251 000, 8 130 000) au lieu de (0250, 8130)
  • chaque dalle fait 5000m de côté et chaque sous-dalle 1000m de côté (en tout cas pour les îles Éparses, mais vérifiez si besoin !)

A vous d’essayer d’écrire un script sur le même principe que précédemment, en remplaçant le paramètre en entrée correspondant à la liste de dalles par un rectangle d’emprise. Toutes les images intersectant ce rectangle d’emprise devront être copiées dans le dossier en sortie !

Ici, le choix a été fait de stocker le rectangle d’emprise sous forme d’un dictionnaire avec 4 clés : xmin, xmax, ymin et ymax. Mais on pourrait très bien utiliser une liste par exemple !

En décomposant par étape :

  1. Calculer l’emprise d’une dalle à partir de son nom et de sa largeur
# un nom de dalle
name = '0250_8130'
# largeur du côté de la dalle dans l'unité du SCR
width = 5000
# récupère les 4 coordonnées
xmin = int(name[0:4]) * 1000
ymax = int(name[5:9]) * 1000
xmax = xmin + width
ymin = ymax - width
bbox_tile = {'xmin' : xmin, 'xmax' : xmax, 'ymin' : ymin, 'ymax' : ymax}
print (bbox_tile)
  1. Calculer l’emprise d’une sous-dalle à partir de son nom et de sa largeur
# un nom de sous-dalle
name = 'LITTO3D_JDN_0255_8126_20120229_UTM38S_WGS84_ZRS'
# largeur du côté de la sous-dalle dans l'unité du SCR
width = 1000
# récupère les 4 coordonnées
xmin = int(name[12:16]) * 1000
ymax = int(name[17:21]) * 1000
xmax = xmin + width
ymin = ymax - width
bbox_tile = {'xmin' : xmin, 'xmax' : xmax, 'ymin' : ymin, 'ymax' : ymax}
print (bbox_tile)
  1. Vérifier si 2 emprises s’intersectent ou non
# https://www.hackerearth.com/practice/notes/how-to-check-if-two-rectangles-intersect-or-not/
# les 2 emprises
bbox1 = {'xmin' : 253676, 'xmax' : 256499, 'ymin' : 8124589, 'ymax' : 8126437}
bbox2 = {'xmin': 250000, 'xmax': 255000, 'ymin': 8125000, 'ymax': 8130000}
# si un rectangle est à gauche de l'autre : pas d'intersection
if bbox1['xmax'] < bbox2['xmin'] or bbox2['xmax'] < bbox1['xmin']:
  print (False)
# si un rectangle est au-dessus de l'autre : pas d'intersection
elif bbox1['ymin'] > bbox2['ymax'] or bbox2['ymin'] > bbox1['ymax']:
  print (False)
else:
  print (True)

Et à vous de jouer pour la suite, en repartant du premier script déjà créé !

Une solution vous est proposée ici, encore une fois il en existe beaucoup d’autres !

On pourrait par exemple utiliser des modules spatiaux comme shapely, et partir d’une couche SIG plutôt que d’un rectangle d’emprise, en extrayant directement les emprises des fichiers ASC puisqu’ils sont géoréférencés…

Le script litto3d_v2.py utilise des fonctions : il s’agit d’une manière d’éviter les redondances, en mettant dans une fonction un bout de code qu’on va réutiliser plusieurs fois. On peut très bien faire sans pour cet exemple, mais si vous voulez en savoir plus sur les fonctions : https://courspython.com/fonctions.html

Option 2 : visualisation de données avec Pandas

Choix d’un module de visualisation de données

L’objectif sera ici de produire des graphiques à partir d’un jeu de données sur les festivals ayant eu lieu en France en 2019.

Il existe de nombreux modules Python dédiés à la visualisation de données.

matplotlib est probablement le plus connu et le plus utilisé. Il permet de créer des graphiques facilement, mais pour une personnalisation un peu poussée il faudra un certain nombre de lignes de code. Cependant, une fois la logique acquise, tout est possible ! Les graphiques peuvent être exportés au format vectoriel (SVG, PDF) pour être modifiés dans un logiciel de dessin, ou bien au format image (JPG, PNG…).

plotly est une librairie qui existe pour de nombreux langages : R, JavaScript, Julia, Matlab… et bien sûr Python ! On peut l’utiliser pour créer des graphiques interactifs au format HTML, qui pourront être intégrés dans une page internet, ou bien statiques, au format vectoriel ou image. plotly.express est une “surcouche” pour plotly, son objectif étant de pouvoir créer des graphiques de la manière la plus simple possible, et s’interface bien avec pandas. C’est ce que nous allons utiliser ici.

Le choix d’un module de visualisation de données est difficile, chacun ayant ses avantages et inconvénients ! Pour une rapide comparaison de 5 d’entre eux, voir ici.

Installation et import

import plotly.express as px

Si le module n’est pas installé, dans un terminal (powershell pour windows) :

conda activate atelier
pip install plotly

Plotly peut produire des graphiques interactifs ou statiques, à vous de choisir !

import plotly.io as pio
pio.renderers.default = 'svg' # pour ouvrir les figures dans spyder (statique)
pio.renderers.default = 'browser' # pour ouvrir les figures dans le navigateur (interactif)

Pour voir les graphiques dans Spyder, le module kaleido sera également nécessaire. Installez-le si ça n’est pas déjà fait et importez-le :

import kaleido

Lecture des données dans un dataframe

Ce jeu de données est disponible sur data.gouv.fr.

Téléchargez le fichier au format CSV et sauvegardez-le sur votre ordinateur. Lisez-le dans un dataframe pandas avec la fonction pandas read_csv.

N’oubliez pas de vérifier quel est le séparateur, en ouvrant par exemple le fichier avec un éditeur de texte type wordpad !

Une fois le dataframe créé, la méthode head() doit vous renvoyer ceci :

fest.head() # ici, le dataframe se nomme fest
##                nom_du_festival  ... identifiant_cnm
## 0         Festival Tête en L’R  ...             NaN
## 1  Les journées de l'éloquence  ...             NaN
## 2  Ma ville est un grand livre  ...             NaN
## 3    Albertville jazz festival  ...             NaN
## 4                 Les Odyssées  ...             NaN
## 
## [5 rows x 30 columns]

Et si vous avez oublié…

path = '../Exo_graphiques/festivals-global-festivals-_-pl.csv'
fest = pd.read_csv(path, sep = ';')
fest.head()

Première exploration des données

Regardez la liste des en-tête de colonnes avec la méthode keys(), ainsi que le nombre de lignes avec len() ou shape.

Regardez également le nombre de valeurs manquantes pour chaque colonne en combinant les fonctions isna() et sum().

print ('colonnes : ')
for key in fest.keys():
  print (key)
print ('nb lignes : ')
len(fest)
print ('Nb valeurs manquantes par colonne : ')
fest.isna().sum()

Premier graphique : histogramme des catégories

Nous allons ici nous intéresser à la colonne discipline_dominante pour voir la distribution des différentes disciplines grâce à un graphique.

Pour information, vous pouvez regarder au préalable le nombre d’occurrences de chaque valeur unique dans la colonne discipline_dominante avec la méthode value_counts() :

## Musique                          3228
## Spectacle vivant                 1633
## Livre, littérature                892
## Cinéma, audiovisuel               685
## Pluridisciplinaire                462
## Arts visuels, arts numériques     382
## Name: discipline_dominante, dtype: int64

Comment créer l’histogramme correspondant ?

Indice 1 :

Vous pouvez utiliser la fonction histogram : https://plotly.com/python/histograms/

Indice 2 :

Cette fonction nécessite 2 arguments : le dataframe, et la colonne qui nous intéresse !

Une solution possible :

fig = px.histogram(fest, 
                    x = 'discipline_dominante',
                    color_discrete_sequence = ['orange']) # pour changer la couleur des barres
fig.show()

Pour info, un simple print sur la figure nous permet de mieux comprendre comment elle fonctionne :

## Figure({
##     'data': [{'alignmentgroup': 'True',
##               'bingroup': 'x',
##               'hovertemplate': 'discipline_dominante=%{x}<br>count=%{y}<extra></extra>',
##               'legendgroup': '',
##               'marker': {'color': 'orange', 'pattern': {'shape': ''}},
##               'name': '',
##               'offsetgroup': '',
##               'orientation': 'v',
##               'showlegend': False,
##               'type': 'histogram',
##               'x': array(['Spectacle vivant', 'Livre, littérature', 'Livre, littérature', ...,
##                           'Spectacle vivant', 'Spectacle vivant', 'Pluridisciplinaire'],
##                          dtype=object),
##               'xaxis': 'x',
##               'yaxis': 'y'}],
##     'layout': {'barmode': 'relative',
##                'legend': {'tracegroupgap': 0},
##                'margin': {'t': 60},
##                'template': '...',
##                'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'title': {'text': 'discipline_dominante'}},
##                'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'title': {'text': 'count'}}}
## })

Personnalisation d’un graphique (titre, couleur…)

Comment faire pour personnaliser ce graphique, par exemple lui donner un titre, modifier les titres des axes et changer la couleur de fond ?

Indice 1 :

Utilisez la méthode update_layout() sur la figure déjà créée !

Indice 2 :

Vous aurez besoin dans update_layout() des arguments suivants
- titre : title
- titre de l axe des X : xaxis_title
- titre de l axe des Y : yaxis_title
- couleur de fond du graphique : paper_bgcolor

Et une solution :

fig.update_layout(
    title = 'Festivals 2019 : catégorie',
    xaxis_title = 'Catégorie',
    yaxis_title = 'Nombre',
    plot_bgcolor = '#FFF8DC' # couleur de la zone de graphique
)

Tri des catégories de l’histogramme

Et si on veut classer les catégories de la plus fréquente à la moins fréquente ?

Indice 1 :

Dans la fonction histogram, utilisez l argument category_orders

Indice 2 :

Cet argument doit être un dictionnaire, avec un seul couple clé/valeur :
- la clé est le nom de la variable
- la valeur est une liste, avec les catégories

Indice 3 :

Pour récupérer les catégories de la plus fréquente à la moins fréquente, vous pouvez utiliser value_counts() et index

Une solution :

var = 'discipline_dominante'
cat_order = {var : list(fest[var].value_counts().index)}
fig = px.histogram(fest, x = var, category_orders = cat_order)
fig.show()

Un script reprenant toutes les commandes vues dans cet exercice est disponible ici.

Traitement de données spatiales

Modules utiles

  • geopandas : manipulation de données tabulaires spatiales
  • rasterio : manipulation de données raster
  • shapely : manipulation de formes géométriques (point, ligne, polygone) et opérations (buffers, jointures, etc.)
  • folium : création de cartes interactives
  • earthpy (basé sur geopandas, rasterio et matplotlib) : données spatiales et télédétection
  • xarray : manipulation de tableaux multidimensionnels (NetCDF)
  • gdal/geos

Exemples d’application :

  • Construire une mosaïque à partir d’image satellites
  • Visualisation de données ERA5
  • Autres ?

Cas d’application 1 : traitement de données vectorielles/raster

Cf. Exercice données spatiales

Cas d’application 2 : traitement d’imagerie satellitaire

Cf. Exercice données satellites