đ Fichiers, đą NumPy
- Fichier (intro)
- Fichier texte
- Fichier CSV
- Fichier JSON
- NumPy (intro)
- Tableaux NumPy
- Calcul vectorisé
- Bornes et correction
- Filtres et masques
- Restructurer sauvegarder
- NumPy et Matplotlib
- Activités
Un fichier c'est quoi?
- un ensemble de données stockées sur un support de stockage (disque dur, SSD, clé USB, carte SD, etc.)
- chaque fichier a un nom et une extension (par exemple
monfichier.txt) - les fichiers peuvent contenir différents types de données : texte, images, vidéos, audio, etc.
- pour lire ou écrire dans un fichier, on utilise des programmes ou des scripts
- chaque fichier utilise un encodage de caractÚres (le standard étant l'UTF-8).
- c'est un peu comme la « table de traduction » permettant à l'ordinateur de transformer les bits (0 et 1) en lettres et en accents.
- sans le bon encodage, le mot
"expérience"pourrait s'afficher comme"expérience". - c'est pourquoi il est important de toujours préciser
encoding="utf-8"dansopen()(ça s'en vient).
Types de fichiers courants (et exemples courants d'extensions)â
- Fichiers texte (.txt, .csv, .json, .xml, etc.)
- Fichiers binaires (.bin, .exe, .dll, etc.)
- Fichiers image (.jpg, .png, .gif, etc.)
- Fichiers audio (.mp3, .wav, .flac, etc.)
- Fichiers vidéo (.mp4, .avi, .mkv, etc.)
OpĂ©rations courantes sur les fichiersâ
- Ouvrir un fichier : pour lire ou écrire des données
- Lire un fichier : pour extraire les données contenues dans le fichier
- Ăcrire dans un fichier : pour ajouter ou modifier des donnĂ©es dans le fichier
- Fermer un fichier : pour libérer les ressources utilisées par le fichier
open() et withEn Python, on utilise la fonction open() pour ouvrir un fichier.
Il est recommandĂ© de l'utiliser avec le mot-clĂ© with, qui garantit que le fichier est automatiquement fermĂ© aprĂšs utilisation, mĂȘme en cas d'erreur.
with open("monfichier.txt", "r", encoding="utf-8") as f: # "r" pour mode lecture
contenu = f.read()
print(contenu)
# Le fichier est automatiquement fermé lorsqu'on sort du bloc with.
Les différents modes d'ouverture sont détaillés dans l'onglet Fichier texte.
Les explications de cette section étaient-elles claires ?
Un fichier texte est un type de fichier trĂšs courant et simple Ă manipuler.
- Il est simplement constitué d'une suite de caractÚres lisibles par l'humain.
- Il ne contient aucun formatage, juste du texte brut.
- Un fichier texte est organisé en lignes, séparées par des caractÚres spéciaux appelés sauts de ligne (
\n). - â
Les scripts Python (
.py) que vous Ă©crivez sont aussi des fichiers texte. - â Un fichier
.docx(Word) ou.pdfcontient du texte, mais aussi beaucoup d'autres informations de formatage, donc ce ne sont pas des fichiers texte.
On peut ouvrir ou créer un fichier texte à la main avec un éditeur de texte (Notepad, PyCharm, VSCode, ...) ou avec du code Python.
Lorsqu'on ouvre un fichier avec open(), on doit préciser ce qu'on veut faire avec lui en passant un mode :
| Mode | Signification | Effet |
|---|---|---|
| "r" | read â lecture | Lit le contenu du fichier |
| "w" | write â Ă©criture | CrĂ©e ou Ă©crase le fichier |
| "a" | append â ajout | Ajoute Ă la fin sans effacer |
đ Mode "r" : Lectureâ
for ligne in fOn peut parcourir un fichier ouvert en mode lecture comme s'il s'agissait d'une liste de lignes, Ă l'aide d'une boucle for :
with open("monfichier.txt", "r", encoding="utf-8") as f:
for ligne in f:
# On peut faire différentes choses avec chaque ligne.
# Par exemple, l'afficher seulement si elle contient le mot "gros" :
if "gros" in ligne:
print(ligne, end="") # end="" pour éviter d'ajouter un 2e retour de ligne \n à la fin
# Ou encore calculer et afficher sa longueur (en caractĂšres) :
print(f"Longueur de la ligne : {len(ligne)} caractĂšres")
read()Supposons que le fichier monfichier.txt contient :
Y a pas deux gros.
Y en a qu'un seul.
Et il est pas gros.
with open("monfichier.txt", "r", encoding="utf-8") as f:
contenu = f.read()
print(contenu)
La variable contenu contiendra alors la chaĂźne de caractĂšres complĂšte du fichier, y compris les sauts de ligne :
Y a pas deux gros.
Y en a qu'un seul.
Et il est pas gros.
readlines()with open("monfichier.txt", "r", encoding="utf-8") as f:
lignes = f.readlines()
print(lignes)
La variable lignes contiendra une liste de chaßnes de caractÚres, chaque chaßne représentant une ligne du fichier, avec les sauts de ligne (\n) inclus :
["Y a pas deux gros.\n", "Y en a qu'un seul.\n", "Et il est pas gros.\n"]
Pour retirer les \n, on peut utiliser la méthode strip() qui retire les espaces et sauts de ligne en début et en fin de chaque chaßne.
C'est l'occasion parfaite d'utiliser une compréhension de liste :
with open("monfichier.txt", "r", encoding="utf-8") as f:
lignes = [ligne.strip() for ligne in f.readlines()]
print(lignes)
Résultat :
["Y a pas deux gros.", "Y en a qu'un seul.", "Et il est pas gros."]
âïž Mode "w" : Ăcritureâ
write()with open("monfichier.txt", "w", encoding="utf-8") as f:
f.write("Bonjour le monde!\n")
f.write("Ceci est un fichier texte.\n")
PlutÎt que d'écrire ligne par ligne, on peut aussi construire une liste puis utiliser join() :
lignes = ["Y a pas deux gros.", "Y en a qu'un seul.", "Et il est pas gros."]
with open("monfichier.txt", "w", encoding="utf-8") as f:
f.write("\n".join(lignes))
La fonction join() prend une liste de chaßnes et les combine en une seule chaßne, en insérant le séparateur (ici \n) entre chaque élément.
â ïžATTENTION : Le mode "w" Ă©crase le contenu existant Ă chaque ouverture. Si le fichier monfichier.txt existait dĂ©jĂ , il sera Ă©crasĂ©, c'est-Ă -dire effacĂ© et remplacĂ© par le nouveau contenu.
â Mode "a" : Ajout (append)â
write() avec "a"Si on veut ajouter des données à la fin d'un fichier sans effacer ce qui s'y trouve déjà , on utilise le mode "a".
Imaginons un fichier journal.txt qui enregistre les héros qui complÚtent un niveau, au fur et à mesure :
# PremiĂšre exĂ©cution â crĂ©e le fichier et Ă©crit la premiĂšre ligne
with open("journal.txt", "a", encoding="utf-8") as f:
f.write("Mario a complété le niveau 1.\n")
# Deuxi Ăšme exĂ©cution â ajoute Ă la fin sans effacer
with open("journal.txt", "a", encoding="utf-8") as f:
f.write("Link a complété le niveau 1.\n")
# TroisiĂšme exĂ©cution â ajoute encore
with open("journal.txt", "a", encoding="utf-8") as f:
f.write("Kirby a complété le niveau 1.\n")
AprÚs ces trois exécutions, journal.txt contiendra :
Mario a complété le niveau 1.
Link a complété le niveau 1.
Kirby a complété le niveau 1.
Si on avait utilisé "w" à la place de "a", seule la derniÚre ligne aurait été conservée.
â ïž Pourquoi toujours utiliser with?â
Sans with, on doit fermer le fichier manuellement avec fichier.close().
Si une erreur survient avant cette ligne, le fichier reste ouvert et les donnĂ©es peuvent ĂȘtre corrompues ou l'accĂšs au fichier bloquĂ©.
# â Ă Ă©viter
fichier = open("monfichier.txt", "r", encoding="utf-8")
contenu = fichier.read()
# Si une erreur survient ici, fichier.close() ne sera jamais appelée!
fichier.close()
# â
Avec with : le fichier est toujours fermĂ©, mĂȘme en cas d'erreur
with open("monfichier.txt", "r", encoding="utf-8") as f:
contenu = f.read()
# Automatiquement fermé ici, quoi qu'il arrive
đš Erreur frĂ©quente : fichier introuvableâ
FileNotFoundError : le fichier n'existe pasSi le nom ou le chemin du fichier est mal écrit, Python lÚve une FileNotFoundError :
with open("monfichierr.txt", "r", encoding="utf-8") as f: # faute de frappe!
contenu = f.read()
FileNotFoundError: [Errno 2] No such file or directory: 'monfichierr.txt'
Cette erreur survient uniquement en mode lecture ("r"). En mode écriture ("w") ou ajout ("a"), Python crée le fichier automatiquement s'il n'existe pas.
Pour l'éviter, vérifiez :
- que le nom du fichier est écrit correctement (majuscules, extension, fautes de frappe)
- que le fichier se trouve dans le mĂȘme dossier que votre script Python
Ouvrir, lire et écrire un fichier texte avec with open(...). Le fichier est automatiquement fermé à la fin du bloc.
| Opération | Syntaxe | Description |
|---|---|---|
| Ouvrir en lecture | with open("f.txt", "r", encoding="utf-8") as f: | Lit le contenu existant |
| Ouvrir en Ă©criture | with open("f.txt", "w", encoding="utf-8") as f: | Ăcrase le contenu existant |
| Ouvrir en ajout | with open("f.txt", "a", encoding="utf-8") as f: | Ajoute Ă la fin sans effacer |
| Lire tout | contenu = f.read() | Retourne une seule chaĂźne (string) |
| Lire en liste | lignes = f.readlines() | Retourne une liste de strings (avec \n) |
| Lire ligne par ligne | for ligne in f: | ItĂšre sur chaque ligne |
| Retirer les sauts de ligne | ligne.strip() | Retire \n en début et fin |
| Ăcrire | f.write("texte\n") | Ăcrit une chaĂźne dans le fichier |
Les explications de cette section étaient-elles claires ?
Un fichier CSV (Comma-Separated Values) est un fichier texte qui organise des données sous forme de tableau.
- Chaque ligne représente un enregistrement.
- Les valeurs de chaque ligne sont séparées par un délimiteur. La virgule (
,) est le plus courant, mais certains fichiers utilisent le point-virgule (;), la tabulation (touche Tab, ou\t), ou mĂȘme l'espace (). C'est pourquoi on parle parfois de fichiers dĂ©limitĂ©s plutĂŽt que strictement CSV. - C'est l'un des formats les plus utilisĂ©s pour Ă©changer des donnĂ©es tabulaires : tableurs, bases de donnĂ©es, rĂ©sultats d'expĂ©riences, etc.
Exemple de contenu d'un fichier mesures.csv :
experience,tentative,ph_mesure,reaction_observee
Acide-base,1,4.7,True
Acide-base,2,5.1,True
Acide-base,3,6.9,False
Dans cette rencontre, l'objectif est surtout de comprendre ce qu'est un fichier CSV et comment Python peut le lire. Les bibliothÚques NumPy et Pandas seront utilisées plus tard dans le cours pour manipuler et analyser des données plus efficacement.
đ Il n'est donc pas nĂ©cessaire d'exĂ©cuter tous les exemples qui suivent : il suffit d'en comprendre le fonctionnement gĂ©nĂ©ral.
Il existe plusieurs façons de lire un fichier CSV en Python. Le choix dépend surtout de ce qu'on veut faire avec les données.
Rappel : il n'est pas nécessaire d'exécuter ces exemples, l'objectif est surtout d'en comprendre le fonctionnement.
Ă partir du fichier mesures.csv :
experience,tentative,ph_mesure,reaction_observee
Acide-base,1,4.7,True
Acide-base,2,5.1,True
Acide-base,3,6.9,False
On pourrait lire les données de plusieurs façons.
1. Ă la main, comme un fichier texteâ
â Inclus avec Python â aucune installation requise.
with open("mesures.csv", "r", encoding="utf-8") as fichier:
for ligne in fichier: # Boucle sur toutes les lignes du fichier
valeurs = ligne.strip().split(",")
print(valeurs)
Résultat :
['experience', 'tentative', 'ph_mesure', 'reaction_observee']
['Acide-base', '1', '4.7', 'True']
['Acide-base', '2', '5.1', 'True']
['Acide-base', '3', '6.9', 'False']
Mais comment chaque ligne de texte est-elle devenue une liste? Tout se joue dans valeurs = ligne.strip().split(",").
Suivons la transformation étape par étape, en prenant la 3e liste affichée ci-dessus (['Acide-base', '2', '5.1', 'True']) :
# Ătape 1 â la ligne lue dans le fichier contient un saut de ligne "\n" Ă la fin :
# "Acide-base,2,5.1,True\n"
#
# Ătape 2 â .strip() retire les espaces et les saut de lignes prĂ©sents :
# "Acide-base,2,5.1,True"
#
# Ătape 3 â .split(",") coupe la chaĂźne Ă chaque virgule et retourne une LISTE :
#
# "Acide-base,2,5.1,True"
# â â â â
# â â â âââââââââââ
# â â ââââââââ â
# â âââââ â â
# â â â â
# ⌠⌠⌠âŒ
# ['Acide-base', '2', '5.1', 'True']
#
# â ïž Chaque valeur est une CHAĂNE de caractĂšres (notez les guillemets),
# mĂȘme les nombres : '2' et '5.1' ne sont PAS encore des nombres.
Cette méthode permet de comprendre qu'un fichier CSV est d'abord un simple fichier texte.
Par contre, il faut tout gĂ©rer soi-mĂȘme : sĂ©parer les valeurs, ignorer l'en-tĂȘte, convertir les nombres, traiter les erreurs, etc.
2. Avec le module csv de Pythonâ
â Inclus avec Python â aucune installation requise.
import csv
with open("mesures.csv", "r", encoding="utf-8") as fichier:
lecteur = csv.reader(fichier)
for ligne in lecteur:
print(ligne)
Résultat :
['experience', 'tentative', 'ph_mesure', 'reaction_observee']
['Acide-base', '1', '4.7', 'True']
['Acide-base', '2', '5.1', 'True']
['Acide-base', '3', '6.9', 'False']
Le module csv est inclus avec Python. Il gÚre mieux la lecture des lignes et des séparateurs qu'une lecture entiÚrement manuelle.
Cependant, les valeurs sont encore lues comme du texte. Il faut donc convertir soi-mĂȘme les nombres, les boolĂ©ens ou les dates au besoin.
3. Avec NumPyâ
đŠ BibliothĂšque externe â Ă installer avec pip install numpy.
import numpy as np
donnees = np.genfromtxt(
"mesures.csv",
delimiter=",",
names=True,
dtype=None,
encoding="utf-8"
)
print(donnees)
Résultat :
[('Acide-base', 1, 4.7, True) ('Acide-base', 2, 5.1, True)
('Acide-base', 3, 6.9, False)]
NumPy peut lire des fichiers CSV, surtout lorsqu'ils contiennent principalement des données numériques.
C'est pratique pour faire des calculs efficacement, lorsque toutes les valeurs sont du mĂȘme type, par exemple des float, mais moins agrĂ©able lorsque les colonnes contiennent des types variĂ©s, comme du texte, des nombres et des valeurs boolĂ©ennes.
4. Avec Pandasâ
đŠ BibliothĂšque externe â Ă installer avec pip install pandas.
import pandas as pd
df = pd.read_csv("mesures.csv")
print(df)
Résultat :
experience tentative ph_mesure reaction_observee
0 Acide-base 1 4.7 True
1 Acide-base 2 5.1 True
2 Acide-base 3 6.9 False
Pandas est plus pratique pour travailler avec des fichiers CSV qui contiennent toutes sortes de données (des mesures, des catégories, etc.). Plus tard dans le cours, nous verrons en détail la bibliothÚque Pandas. Il charge les données dans un tableau structuré appelé DataFrame, reconnaßt souvent automatiquement les types de données et facilite ensuite le filtrage, le tri, les calculs et les visualisations.
Comparaison rapideâ
| Méthode | Installation | Avantage principal | Limite principale |
|---|---|---|---|
| Lecture manuelle | â Aucune | Permet de comprendre la structure du fichier, Permet un contrĂŽle total (parfois utile) | Il faut tout gĂ©rer soi-mĂȘme |
Module csv | â Aucune | Inclus avec Python et adaptĂ© aux fichiers CSV simples | Les valeurs restent principalement du texte |
| NumPy | đŠ pip install numpy | TrĂšs utile pour les donnĂ©es numĂ©riques (par exemple tous des float) | Moins pratique pour les tableaux avec des types variĂ©s |
| Pandas | đŠ pip install pandas | TrĂšs pratique pour analyser des donnĂ©es tabulaires | BibliothĂšque externe Ă installer |
Les explications de cette section étaient-elles claires ?
Le JSON (JavaScript Object Notation) est un format de fichier texte conçu pour stocker et échanger des données structurées.
- Il est lisible par les humains : on peut l'ouvrir dans n'importe quel Ă©diteur de texte et comprendre son contenu d'un coup d'Ćil.
- Il est facile Ă utiliser avec Python : le module
json(inclus avec Python, aucune installation nĂ©cessaire) permet de lire et d'Ă©crire du JSON en quelques lignes. - Il supporte les mĂȘmes types que Python : chaĂźnes, nombres, boolĂ©ens, listes et dictionnaires.
Un fichier .txt contient du texte brut sans structure. Si on veut sauvegarder plusieurs informations liĂ©es entre elles (par exemple le profil d'un joueur avec son nom, son score et ses niveaux complĂ©tĂ©s), il faut inventer soi-mĂȘme une façon d'organiser les donnĂ©es, et la relire devient vite compliquĂ©.
Le JSON résout ce problÚme : il sauvegarde directement la structure des données (dictionnaires, listes imbriquées) et Python peut la reconstruire automatiquement à la lecture.
import json
json.dump()Imaginons qu'on veuille sauvegarder les données d'une expérience en laboratoire :
import json
experience = {
"nom": "Réaction acide-base",
"tentative": 3,
"ph_mesure": 4.7,
"reaction_observee": True,
"reactifs": ["HCl", "NaOH", "eau distillée"]
}
with open("experience.json", "w", encoding="utf-8") as f:
json.dump(experience, f, indent=4, ensure_ascii=False)
Le fichier experience.json contiendra alors :
{
"nom": "Réaction acide-base",
"tentative": 3,
"ph_mesure": 4.7,
"reaction_observee": true,
"reactifs": ["HCl", "NaOH", "eau distillée"]
}
đĄ L'argument indent=4 ajoute des indentations pour rendre le fichier plus lisible. Sans lui, tout serait sur une seule ligne.
đĄ L'argument ensure_ascii=False permet de conserver les caractĂšres spĂ©ciaux (comme les accents) tels quels, au lieu de les convertir en sĂ©quences d'Ă©chappement ASCII. Le fichier JSON restera ainsi plus lisible.
json.load()Pour récupérer les données sauvegardées et les utiliser dans Python, on utilise json.load().
Le rĂ©sultat est directement un dictionnaire Python, prĂȘt Ă ĂȘtre utilisĂ©.
import json
with open("experience.json", "r", encoding="utf-8") as f:
experience = json.load(f)
print(f"Expérience : {experience['nom']}") # Expérience : Réaction acide-base
print(f"Tentative #{experience['tentative']}") # Tentative #3
print(f"pH mesuré : {experience['ph_mesure']}") # pH mesuré : 4.7
print(f"Réaction observée : {experience['reaction_observee']}") # Réaction observée : True
print(f"Réactifs : {experience['reactifs']}") # Réactifs : ['HCl', 'NaOH', 'eau distillée']
đ On accĂšde aux valeurs exactement comme dans n'importe quel dictionnaire Python, parce que c'en est un!
Le JSON ressemble beaucoup Ă la syntaxe Python, et ce n'est pas un hasard : les deux utilisent des accolades {} pour les structures clĂ©-valeur et des crochets [] pour les listes. Si on sait dĂ©jĂ lire du Python, un fichier JSON semblera familier du premier coup d'Ćil.
Par contre, JSON est un format d'échange universel (pas lié à Python), donc il a ses propres rÚgles strictes :
| Python | JSON |
|---|---|
| True / False | true / false (minuscules) |
| None | null |
| Guillemets simples 'abc' acceptés | Seulement guillemets doubles "abc" |
| Tuples (1, 2) | Pas de tuples, convertis en listes [1, 2] |
| Commentaires # ... | Pas de commentaires |
La bonne nouvelle : json.dump() et json.load() gĂšrent toutes ces conversions automatiquement.
On écrit du Python, Python traduit en JSON, et vice-versa. On n'a pas à s'en préoccuper, ni à le retenir.
Le format JSON est particuliĂšrement utile dans le cours 420-4A4 : RĂ©seaux de neurones et sciences, oĂč il est utilisĂ© pour conserver les hyperparamĂštres des rĂ©seaux de neurones entre les expĂ©riences (taux d'apprentissage, nombre de couches, taille des lots, etc.).
| Situation | Format recommandé |
|---|---|
| Données simples, ligne par ligne | Fichier texte (.txt) |
| Données structurées (dictionnaires, listes imbriquées) | JSON (.json) |
| Données tabulaires (tableau de valeurs) | CSV (.csv) |
Sauvegarder et relire des structures Python (dictionnaires, listes) avec le module import json, inclus avec Python.
| Opération | Syntaxe | Description |
|---|---|---|
| Importer | import json | Module inclus, aucune installation requise |
| Sauvegarder | json.dump(data, f, indent=4, ensure_ascii=False) | Ăcrit un objet Python dans un fichier JSON |
| Charger | data = json.load(f) | Lit un objet Python Ă partir d'un fichier JSON |
Les explications de cette section étaient-elles claires ?
đŁ NumPy se prononce nomme-paille
Jusquâici, pour travailler avec une liste de nombres, il fallait utiliser des boucles for : une itĂ©ration par Ă©lĂ©ment, une opĂ©ration Ă la fois.
Ăa fonctionne, mais câest lent et verbeux dĂšs quâon manipule des milliers de valeurs.
Câest lĂ quâintervient đą NumPy : une bibliothĂšque Python conçue pour effectuer des calculs sur des tableaux en une seule instruction, sans boucle, et Ă une vitesse bien supĂ©rieure!
| Onglet | Ce quâon y apprend |
|---|---|
| Tableaux NumPy | Créer un tableau, comprendre shape et dtype |
| Calcul vectorisé | Appliquer une opération à tout un tableau sans boucle |
| Bornes et correction | Encadrer des valeurs avec clip(), maximum(), minimum() |
| Filtres et masques | Filtrer, vérifier et transformer selon des conditions |
| Restructurer sauvegarder | Restructurer, combiner, générer aléatoirement, sauvegarder |
| NumPy et Matplotlib | Tracer des graphiques Ă partir de tableaux NumPy |
NumPy nâest quâune des bibliothĂšques Python trĂšs utilisĂ©es en sciences.
Pour votre culture gĂ©nĂ©rale, voici comment elle sâinscrit dans lâĂ©cosystĂšme Python scientifique :
- đą NumPy : calcul sur des tableaux numĂ©riques - câest le sujet de ces onglets
- đŒ Pandas : manipulation de donnĂ©es tabulaires - sera vue Ă la rencontre 11
- đ Matplotlib : visualisation de donnĂ©es - on la connait dĂ©jĂ
- đ€ Scikit-learn : apprentissage automatique - un aperçu Ă la rencontre 15
- đ§ Keras / TensorFlow : apprentissage profond - utilisĂ©es dans le cours RĂ©seaux de neurones
NumPy nâest pas inclus avec Python. Il faut lâinstaller avant de pouvoir lâutiliser.
Consulter la recette dâinstallation de bibliothĂšques pour savoir comment faire, ou exĂ©cuter cette commande dans le terminal :
pip install numpy
Les explications de cette section étaient-elles claires ?
En Python, une liste peut contenir nâimporte quoi : des nombres, des strings, des listes, des objets mĂ©langĂ©s.
ma_liste = [1, "deux", 3.0, [4, 5], {"six": 6}]
Câest trĂšs flexible, mais cette flexibilitĂ© a un coĂ»t : Python doit vĂ©rifier le type de chaque Ă©lĂ©ment un par un.
Un tableau NumPy (ndarray) est diffĂ©rent : tous ses Ă©lĂ©ments ont le mĂȘme type.
NumPy tire profit de cette contrainte pour effectuer des calculs beaucoup plus rapidement, en traitant le tableau entier dâun seul bloc plutĂŽt quâĂ©lĂ©ment par Ă©lĂ©ment.
La convention universelle est dâimporter NumPy avec lâalias np :
import numpy as np
Vous verrez import numpy as np au dĂ©but de tous les scripts qui utilisent NumPy. Câest une convention que tout le monde respecte. Utilisez-la aussi.
Il existe plusieurs façons de créer un tableau selon le contexte :
Ă partir dâune liste existante :
liste = [1, 2, 3, 4, 5]
tab_numpy = np.array(liste)
print(tab_numpy) # [1 2 3 4 5]
print(type(tab_numpy)) # <class ânumpy.ndarrayâ>
Avec des valeurs prédéfinies :
zeros = np.zeros(5) # [0. 0. 0. 0. 0.] 5 zéros (initialiser un tableau vide)
uns = np.ones(5) # [1. 1. 1. 1. 1.] 5 uns
neufs = np.full(5, 9) # [9 9 9 9 9] 5 fois la valeur 9
Avec des séquences de valeurs :
sequence = np.arange(0, 10, 2) # [0 2 4 6 8] entiers de 0 Ă 9 par pas de 2
# (fonctionne comme la fonction range())
intervalle = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1. ] 5 valeurs réguliÚrement espacées entre 0 et 1
đĄ La diffĂ©rence clĂ© entre np.arange() et np.linspace() :
- avec
np.arange()on choisit le pas entre chaque valeur - avec
np.linspace()on choisit le nombre de points souhaité.
Pour les graphiques, np.linspace() est presque toujours préférable, car on sait exactement combien de points on aura.
liste = [1, 2, 3, 4, 5]
tab_numpy = np.array(liste)
print(liste) # [1, 2, 3, 4, 5]
print(tab_numpy) # [1 2 3 4 5]
print(type(liste)) # <class 'list'>
print(type(tab_numpy)) # <class 'numpy.ndarray'>
Les valeurs sont les mĂȘmes, mais NumPy retire les virgules Ă l'affichage. Le type() confirme qu'il s'agit bien de deux objets diffĂ©rents â une list Python et un ndarray NumPy.
shape et dtype : deux propriétés essentiellesCe sont les deux premiÚres choses à vérifier sur un tableau inconnu.
shape - la forme du tableau (ses dimensions), sous forme de tuple :
tab_1d = np.array([10, 20, 30, 40, 50])
print(tab_1d.shape) # (5,) tableau 1D de 5 éléments
NumPy supporte les tableaux Ă plusieurs dimensions. Un tableau 2D ressemble Ă une grille (lignes et colonnes) :
tab_2d = np.array([[1, 2, 3],
[4, 5, 6]])
print(tab_2d.shape) # (2, 3) 2 lignes, 3 colonnes
Dans ce cours, nous travaillerons presque exclusivement avec des tableaux 1D. Les tableaux 2D seront davantage utilisés dans les cours suivants (Réseaux de neurones, Projet scientifique), mais il est bon de savoir que NumPy peut gérer des tableaux de n'importe quelle dimension (2D, 42D, ...).
size - le nombre total dâĂ©lĂ©mentsprint(tab_2d.size) # 6 (2 lignes x 3 colonnes)
dtype - le type des données stockées :
tab_entiers = np.array([1, 2, 3])
tab_decimaux = np.array([1.0, 2.0, 3.0])
tab_booleens = np.array([True, False, True])
print(tab_entiers.dtype) # int64 entiers
print(tab_decimaux.dtype) # float64 décimaux
print(tab_booleens.dtype) # bool booléens
Si on crée un tableau avec par exemple à la fois des nombres entiers et des nombres décimaux, NumPy choisit automatiquement le type le plus général :
tab_mixte = np.array([1, 2, 3.0])
print(tab_mixte.dtype) # float64 NumPy a converti tous les entiers en décimaux
print(tab_mixte) # [1. 2. 3.] Les décimaux sont affichés avec un point décimal
Câest souvent le comportement voulu, mais il faut en ĂȘtre conscient.
shape, size et dtype sont des propriétésNotez bien que shape, size et dtype sont des propriétés du tableau, pas des fonctions.
On les appelle sans parenthĂšses, contrairement Ă une fonction :
nb_elements = tab_1d.size # Correct : nb_elements contient le nombre d'éléments
nb_elements = tab_1d.size() # Incorrect : TypeError, car size n'est pas une fonction
On accĂšde aux Ă©lĂ©ments dâun tableau exactement comme pour une liste Python :
tableau = np.array([10, 20, 30, 40, 50])
print(tableau[0]) # 10 â premier Ă©lĂ©ment
print(tableau[-1]) # 50 â dernier Ă©lĂ©ment
print(tableau[1:4]) # [20 30 40] â Ă©lĂ©ments de l'index 1 (inclus) Ă l'index 4 (exclus)
| Opération | Syntaxe | Description |
|---|---|---|
| Importer NumPy | import numpy as np | Convention universelle |
| Depuis une liste | tab_numpy = np.array([1, 2, 3]) | Convertit une liste en tableau |
| Tableau de zéros | tab_numpy = np.zeros(5) | Tableau de 5 zéros (float64) |
| Tableau de uns | tab_numpy = np.ones(5) | Tableau de 5 uns (float64) |
| Tableau avec valeur fixe | tab_numpy = np.full(5, 9) | Tableau de 5 neufs |
| Séquence entiÚre | tab_numpy = np.arange(0, 10, 2) | [0 2 4 6 8] comme range() |
| Séquence espacée | tab_numpy = np.linspace(0, 1, 5) | 5 valeurs entre 0 et 1 (inclus) |
| Forme du tableau | forme = tab_numpy.shape | Retourne (lignes, colonnes) |
| Type des données | type_donnees = tab_numpy.dtype | Ex : float64, int64, bool |
| Nombre d'éléments | nb_elements = tab_numpy.size | Nombre total d'éléments |
| AccÚs par indice | element = tab_numpy[2] | 3e élément (indice commence à 0) |
| Sous-tableau | sous_tab = tab_numpy[1:4] | ĂlĂ©ments d'indices 1, 2, 3 |
Les explications de cette section étaient-elles claires ?
En Python ordinaire, pour ajouter 5 Ă toutes les valeurs dâune liste, on doit Ă©crire une boucle :
# Avec une liste Python : une boucle obligatoire
valeurs = [10, 20, 30, 40, 50]
doubles = [v + 5 for v in valeurs] # [15, 25, 35, 45, 55]
Avec NumPy, lâopĂ©ration sâapplique Ă tout le tableau dâun seul coup, sans boucle :
# Avec NumPy : une seule ligne, bien plus rapide
import numpy as np
valeurs = np.array([10, 20, 30, 40, 50])
doubles = valeurs + 5 # [15 25 35 45 55]
Câest ce quâon appelle la vectorisation : NumPy effectue lâopĂ©ration sur tous les Ă©lĂ©ments simultanĂ©ment.
Sur de petites listes la différence de vitesse est imperceptible, mais sur des millions de valeurs, elle devient dramatique. Voici un exemple concret avec la mesure du temps de calcul pour doubler une liste de 1 million de valeurs :
import numpy as np
import time
n = 1_000_000 # 1 million de valeurs
# Avec une liste Python
valeurs_liste = list(range(n))
debut = time.time()
doubles_liste = [v * 2 for v in valeurs_liste]
print(f"Boucle Python : {time.time() - debut:.4f} secondes")
# Avec NumPy
valeurs_numpy = np.arange(n)
debut = time.time()
doubles_numpy = valeurs_numpy * 2
print(f"NumPy : {time.time() - debut:.4f} secondes")
Le résultat typique ressemble à :
Boucle Python : 0.0850 secondes
NumPy : 0.0012 secondes
NumPy est environ 70 fois plus rapide sur cet exemple. LâĂ©cart grandit encore sur des opĂ©rations plus complexes.
Tous les opĂ©rateurs habituels (+, -, *, /, **) sâappliquent Ă©lĂ©ment par Ă©lĂ©ment sur un tableau NumPy :
x = np.array([1, 2, 3, 4, 5])
print(x + 10) # [11 12 13 14 15]
print(x * 3) # [ 3 6 9 12 15]
print(x ** 2) # [ 1 4 9 16 25]
print(x / 2) # [0.5 1. 1.5 2. 2.5]
On peut aussi faire des opĂ©rations entre deux tableaux de mĂȘme taille, et NumPy appliquera lâopĂ©ration Ă chaque paire dâĂ©lĂ©ments correspondants :
a = np.array([1, 2, 3])
b = np.array([10, 20, 30])
print(a + b) # [11 22 33]
print(a * b) # [10 40 90]
NumPy fournit des versions vectorisĂ©es de toutes les fonctions mathĂ©matiques courantes. Elles sâappliquent Ă chaque Ă©lĂ©ment du tableau sans boucle :
angles = np.linspace(0, np.pi, 5) # [0, Ï/4, Ï/2, 3Ï/4, Ï]
print(np.sin(angles)) # [0. 0.707 1. 0.707 0. ]
print(np.cos(angles)) # [1. 0.707 0. -0.707 -1. ]
valeurs = np.array([4.0, 9.0, 16.0, 25.0])
print(np.sqrt(valeurs)) # [2. 3. 4. 5.]
donnees = np.array([-3.7, 1.2, -0.5, 4.9])
print(np.abs(donnees)) # [3.7 1.2 0.5 4.9] valeur absolue : retire le signe négatif
print(np.floor(donnees)) # [-4. 1. -1. 4.] arrondi vers le bas (ex. -3.7 â -4, pas -3)
print(np.ceil(donnees)) # [-3. 2. 0. 5.] arrondi vers le haut (ex. -3.7 â -3, pas -4)
Ces fonctions calculent une valeur unique Ă partir de tout le tableau :
scores = np.array([72, 85, 61, 90, 78])
print(np.sum(scores)) # 386
print(np.mean(scores)) # 77.2
print(np.min(scores)) # 61
print(np.max(scores)) # 90
print(np.std(scores)) # 10.88 écart-type : mesure à quel point les valeurs s'éloignent de la moyenne
# (0 = toutes identiques, grand = trÚs dispersées)
argmax() et argmin() : trouver lâindice du maximum/minimumPlutĂŽt que de retourner la valeur maximale ou minimale, argmax() et argmin() retournent lâindex de cet Ă©lĂ©ment dans le tableau.
Câest utile pour retrouver quel Ă©lĂ©ment a obtenu le meilleur (ou le pire) rĂ©sultat.
scores = np.array([72, 85, 61, 90])
noms = ["Astro", "Peluche", "ChatmouraĂŻ", "Mini-boulette"]
indice_max = np.argmax(scores) # 3 Mini-boulette a le score le plus élevé
indice_min = np.argmin(scores) # 2 ChatmouraĂŻ a le score le plus bas
print(f"Meilleur score : {noms[indice_max]} avec {scores[indice_max]}")
# Meilleur score : Mini-boulette avec 90
argmax() vs max()np.max(scores) retourne 90 (la valeur).
np.argmax(scores) retourne 3 (la position).
Les deux sont utiles selon le contexte.
| Opération | Syntaxe | Description |
|---|---|---|
| Importer NumPy | import numpy as np | Convention universelle |
| Addition | tab_resultat = tab_numpy + 5 | Ajoute 5 à chaque élément |
| Multiplication | tab_resultat = tab_numpy * 2 | Multiplie chaque élément par 2 |
| Puissance | tab_resultat = tab_numpy ** 2 | Met chaque élément au carré |
| Addition Ă©lĂ©ment par Ă©lĂ©ment | tab_resultat = tab_a + tab_b | Additionne deux tableaux de mĂȘme taille |
| Sinus | tab_resultat = np.sin(tab_numpy) | Calcule sin() sur chaque élément |
| Cosinus | tab_resultat = np.cos(tab_numpy) | Calcule cos() sur chaque élément |
| Racine carrée | tab_resultat = np.sqrt(tab_numpy) | Racine carrée de chaque élément |
| Valeur absolue | tab_resultat = np.abs(tab_numpy) | Valeur absolue de chaque élément |
| Exponentielle | tab_resultat = np.exp(tab_numpy) | e^x pour chaque élément |
| Arrondi inférieur | tab_resultat = np.floor(tab_numpy) | Arrondi vers le bas (ex. -3.7 devient -4) |
| Arrondi supérieur | tab_resultat = np.ceil(tab_numpy) | Arrondi vers le haut (ex. -3.7 devient -3) |
| Somme | total = np.sum(tab_numpy) | Somme de tous les éléments |
| Moyenne | moyenne = np.mean(tab_numpy) | Moyenne de tous les éléments |
| Minimum | minimum = np.min(tab_numpy) | Valeur minimale |
| Maximum | maximum = np.max(tab_numpy) | Valeur maximale |
| Ăcart-type | ecart = np.std(tab_numpy) | Mesure la dispersion (Ă©cart-type) |
| Indice du maximum | indice = np.argmax(tab_numpy) | Indice de la valeur la plus grande |
| Indice du minimum | indice = np.argmin(tab_numpy) | Indice de la valeur la plus petite |
Les explications de cette section étaient-elles claires ?
Dans de nombreuses situations rĂ©elles, les valeurs calculĂ©es ou mesurĂ©es peuvent dĂ©passer des limites physiques ou logiques : une luminositĂ© ne peut pas ĂȘtre nĂ©gative ni dĂ©passer 1, une coordonnĂ©e sur un Ă©cran ne peut pas sortir de la fenĂȘtre, un pourcentage doit rester entre 0 et 100.
NumPy fournit des fonctions pour corriger ou encadrer automatiquement des valeurs hors limites, sans écrire de conditions if ni de boucles.
np.clip() - ramener des valeurs entre une borne minimum et un maximumOn utilise np.clip(tableau, min, max) quand on connait Ă lâavance deux bornes (un minimum ET un maximum) et qu'on veut garantir que toutes les valeurs restent dans cet intervalle en une seule instruction.
Pour chaque élément du tableau :
- si la valeur est infĂ©rieure Ă
min, elle devientmin; - si la valeur est supĂ©rieure Ă
max, elle devientmax; - sinon, elle reste inchangée.
Un capteur de pH mesure lâaciditĂ© dâune solution. Les valeurs valides se situent entre 0 et 14, mais le capteur peut retourner des valeurs aberrantes Ă cause du bruit de mesure. On veut corriger ces mesures avant de les analyser :
mesures_ph = np.array([-0.3, 4.2, 7.1, 14.8, 6.9])
mesures_valides = np.clip(mesures_ph, 0, 14)
print(mesures_valides) # [ 0. 4.2 7.1 14. 6.9]
La mesure -0.3 est ramenée à 0 et la mesure 14.8 est ramenée à 14. Les autres sont restées intactes.
np.maximum() et np.minimum() - appliquer une borne ou comparer deux tableauxLes fonctions np.maximum() et np.minimum() peuvent servir à deux choses différentes :
- appliquer une seule borne Ă un tableau;
- comparer deux tableaux position par position.
Contrairement à np.clip(), qui applique une borne minimale et une borne maximale en une seule instruction, np.maximum() et np.minimum() permettent de corriger seulement un cÎté à la fois.
1. Appliquer une borne avec une constanteâ
On utilise np.maximum(tableau, valeur_min) pour imposer un minimum.
Autrement dit, chaque valeur plus petite que valeur_min est remplacée par valeur_min.
import numpy as np
intensites = np.array([-0.2, 0.0, 0.4, 0.8, 1.3])
intensites_sans_negatif = np.maximum(intensites, 0)
print(intensites_sans_negatif)
Résultat :
[0. 0. 0.4 0.8 1.3]
Ici, la valeur -0.2 est ramenée à 0. Les autres valeurs restent inchangées.
On utilise plutĂŽt np.minimum(tableau, valeur_max) pour imposer un maximum.
Autrement dit, chaque valeur plus grande que valeur_max est remplacée par valeur_max.
intensites_limitees = np.minimum(intensites_sans_negatif, 1)
print(intensites_limitees)
Résultat :
[0. 0. 0.4 0.8 1. ]
Ici, la valeur 1.3 est ramenée à 1.
Dans cet exemple, les valeurs représentent une intensité normalisée, par exemple une luminosité ou une probabilité.
Elles devraient normalement rester entre 0 et 1, mais un calcul ou une mesure peut parfois produire une valeur légÚrement hors limites.
On pourrait donc écrire :
intensites = np.array([-0.2, 0.0, 0.4, 0.8, 1.3])
intensites_corrigees = np.maximum(intensites, 0)
intensites_corrigees = np.minimum(intensites_corrigees, 1)
print(intensites_corrigees)
Résultat :
[0. 0. 0.4 0.8 1. ]
Cette méthode donne un résultat semblable à np.clip(intensites, 0, 1), mais en appliquant les deux bornes séparément.
2. Comparer deux tableaux position par positionâ
np.maximum() et np.minimum() peuvent aussi comparer deux tableaux de mĂȘme taille.
Dans ce cas :
np.maximum(tableau_a, tableau_b)prend la plus grande valeur Ă chaque position;np.minimum(tableau_a, tableau_b)prend la plus petite valeur Ă chaque position.
Par exemple, imaginons deux séries de mesures prises par deux capteurs différents :
capteur_a = np.array([12.1, 13.5, 11.8, 14.2])
capteur_b = np.array([12.4, 13.1, 12.0, 13.9])
mesures_max = np.maximum(capteur_a, capteur_b)
mesures_min = np.minimum(capteur_a, capteur_b)
print(mesures_max)
print(mesures_min)
Résultat :
[12.4 13.5 12. 14.2]
[12.1 13.1 11.8 13.9]
Le premier tableau contient donc, pour chaque position, la mesure la plus élevée des deux capteurs. Le deuxiÚme tableau contient, pour chaque position, la mesure la plus basse.
Cela peut ĂȘtre utile lorsqu'on veut crĂ©er un tableau des extrĂȘmes locaux entre deux sĂ©ries de donnĂ©es : par exemple les valeurs les plus hautes et les plus basses mesurĂ©es par deux instruments, deux simulations ou deux scĂ©narios.
np.max() vs np.maximum() : ne pas confondrevaleurs = np.array([3, 7, 1, 9, 4])
print(np.max(valeurs)) # 9 une seule valeur : le maximum du tableau
print(np.maximum(valeurs, 5)) # [5 7 5 9 5] un tableau : compare chaque élément à 5
np.max() résume le tableau en une valeur.
np.maximum() produit un nouveau tableau de mĂȘme taille.
| Opération | Syntaxe | Description |
|---|---|---|
| Importer NumPy | import numpy as np | Convention universelle |
| Limiter entre un min et un max | tab_resultat = np.clip(tab_numpy, 0, 1) | Chaque valeur est ramenée entre 0 et 1 |
| Appliquer un minimum | tab_resultat = np.maximum(tab_numpy, 0) | Remplace les valeurs plus petites que 0 par 0 |
| Appliquer un maximum | tab_resultat = np.minimum(tab_numpy, 100) | Remplace les valeurs plus grandes que 100 par 100 |
| Maximum entre deux tableaux | tab_resultat = np.maximum(tab_a, tab_b) | ĂlĂ©ment par Ă©lĂ©ment, prend le plus grand |
| Minimum entre deux tableaux | tab_resultat = np.minimum(tab_a, tab_b) | ĂlĂ©ment par Ă©lĂ©ment, prend le plus petit |
Les explications de cette section étaient-elles claires ?
En sciences, on travaille rarement avec toutes les donnĂ©es en mĂȘme temps. On veut souvent isoler les mesures qui dĂ©passent un seuil, remplacer les valeurs aberrantes, ou classer les rĂ©sultats selon une condition : par exemple garder seulement les tempĂ©ratures au-dessus de 0°C, ou Ă©tiqueter les concentrations selon quâelles sont en zone sĂ»re ou non.
En Python ordinaire, chacune de ces opérations demande une boucle avec un if.
Avec NumPy, on exprime la condition directement sur le tableau entier en une seule ligne, peu importe sâil contient 10 ou 10 millions de valeurs.
Un masque boolĂ©en est un tableau de True et False de la mĂȘme taille qu'un tableau de donnĂ©es.
Chaque True indique un élément qui satisfait la condition, chaque False un élément qui ne la satisfait pas.
valeurs = np.array([4, -2, 7, -1, 0, 3])
masque = valeurs < 0
print(masque) # [False True False True False False]
On peut ensuite utiliser ce masque pour extraire/filtrer les éléments qui satisfont la condition :
negatifs = valeurs[masque]
print(negatifs) # [-2 -1]
Ces deux blocs sont équivalents. Le raccourci est plus courant en pratique :
# Version avec masque intermédiaire
masque = valeurs < 0
negatifs = valeurs[masque]
# Version directe (raccourci)
negatifs = valeurs[valeurs < 0]
On peut combiner plusieurs conditions avec & (ET) et | (OU). Chaque condition doit ĂȘtre entre parenthĂšses.
tableau = np.array([5, 12, 18, 25, 30, 3])
# ET : les deux conditions vraies simultanément
entre_10_et_20 = tableau[(tableau >= 10) & (tableau <= 20)]
print(entre_10_et_20) # [12 18]
# OU : au moins une condition vraie
extremes = tableau[(tableau < 5) | (tableau > 25)]
print(extremes) # [30 3]
Si on crée d'abord un masque, il faut aussi des parenthÚses autour de chaque condition lorsqu'il y en a plusieurs :
masque = (tableau >= 10) & (tableau <= 20)
entre_10_et_20 = tableau[masque]
np.any() et np.all() - vĂ©rifier des conditions globalesCes deux fonctions posent une question sur lâensemble du tableau et retournent un seul True ou False :
np.any(condition): est-ce quâau moins un Ă©lĂ©ment satisfait la condition?np.all(condition): est-ce que tous les Ă©lĂ©ments satisfont la condition?
Par exemple, un chercheur a mesurĂ© la pression atmosphĂ©rique Ă 6 stations mĂ©tĂ©o. Avant dâanalyser les donnĂ©es, il veut vĂ©rifier leur validitĂ© :
pressions = np.array([1012.3, 998.7, 1021.5, -5.0, 1008.1, 1015.4])
anomalie_detectee = np.any(pressions < 0) # Y a-t-il au moins une mesure invalide (pression négative)?
print(anomalie_detectee) # True â une valeur aberrante a Ă©tĂ© dĂ©tectĂ©e
toutes_valides = np.all((pressions >= 900) & (pressions <= 1100)) # Toutes les mesures sont-elles dans une plage réaliste?
print(toutes_valides) # False â la valeur -5.0 sort de la plage
On utilise souvent ces fonctions dans un if pour stopper le traitement si les données sont invalides :
if np.any(pressions < 0):
print("Attention : des mesures invalides ont été détectées.")
else:
print("Toutes les mesures sont valides, analyse en cours.")
np.where() - choisir une valeur selon une conditionLe filtrage vu prĂ©cĂ©demment permet d'extraire des valeurs selon une condition. Mais parfois, on ne veut pas rĂ©duire le tableau : on veut produire un nouveau tableau de mĂȘme taille, oĂč chaque position reçoit une valeur selon une condition.
C'est exactement le rĂŽle de np.where().
np.where() prend trois arguments :
np.where(condition, choix_si_vrai, choix_si_faux)
Pour chaque élément, NumPy pose la question de la condition :
- si la réponse est vraie, le résultat prend la valeur de
choix_si_vrai; - si la réponse est fausse, le résultat prend la valeur de
choix_si_faux.
Le tableau rĂ©sultant a toujours la mĂȘme taille que le tableau de dĂ©part.
Que peut-on mettre dans les deux choix?â
Les deux choix peuvent ĂȘtre :
- une nouvelle valeur fixe;
- la valeur originale du tableau;
- une valeur provenant dâun autre tableau.
Par exemple :
# Remplacer certaines valeurs et garder les autres
corrigees = np.where(concentrations < 0, 0, concentrations)
# MĂȘme idĂ©e, mais avec la condition inversĂ©e
corrigees = np.where(concentrations >= 0, concentrations, 0)
# Choisir entre deux nouvelles valeurs
classification = np.where(mesures_ph < 7, "acide", "basique/neutre")
# Choisir entre deux tableaux
resultat = np.where(condition, tableau_a, tableau_b)
Dans tous les cas, NumPy fait le mĂȘme travail : il choisit une valeur Ă chaque position.
Exemple 1 : remplacer certaines valeurs et garder les autresâ
Par exemple, un biologiste mesure des concentrations en solution.
Les valeurs nĂ©gatives sont physiquement impossibles et doivent ĂȘtre remplacĂ©es par 0.
Les valeurs valides, elles, doivent rester telles quelles.
import numpy as np
concentrations = np.array([4.2, -0.3, 7.1, -1.5, 0.0, 3.8])
corrigees = np.where(concentrations < 0, # condition : est-ce que la valeur est négative?
0, # si oui : remplacer par 0
concentrations) # si non : garder la valeur dâorigine
print(corrigees)
Résultat :
[4.2 0. 7.1 0. 0. 3.8]
Ici, les valeurs négatives sont remplacées par 0.
Les autres valeurs sont conservées.
On aurait aussi pu Ă©crire la condition dans lâautre sens :
corrigees = np.where(concentrations >= 0, # condition : est-ce que la valeur est valide?
concentrations, # si oui : garder la valeur dâorigine
0) # si non : remplacer par 0
Le rĂ©sultat serait le mĂȘme.
Exemple 2 : choisir entre deux nouvelles valeursâ
Parfois, on ne veut pas garder les valeurs dâorigine. On veut plutĂŽt produire un nouveau tableau oĂč chaque Ă©lĂ©ment reçoit une nouvelle valeur selon la condition.
Par exemple, un technicien veut attribuer automatiquement une étiquette à chaque mesure de pH :
mesures_ph = np.array([3.1, 7.0, 8.5, 4.2, 6.9])
classification = np.where(mesures_ph < 7, # condition : est-ce que le pH est inférieur à 7?
"acide", # si oui : écrire "acide"
"basique/neutre") # si non : écrire "basique/neutre"
print(classification)
Résultat :
['acide' 'basique/neutre' 'basique/neutre' 'acide' 'acide']
Dans cet exemple, aucune valeur numĂ©rique dâorigine nâest conservĂ©e. Chaque Ă©lĂ©ment est remplacĂ© par une nouvelle valeur.
Cette forme peut servir à créer des catégories, comme ici, mais aussi des codes numériques :
codes = np.where(mesures_ph < 7, 0, 1)
print(codes)
Résultat :
[0 1 1 0 0]
Exemple 3 : choisir entre deux tableauxâ
Les deux choix peuvent aussi ĂȘtre deux tableaux (de mĂȘme taille).
Dans ce cas, NumPy choisit, Ă chaque position, une valeur provenant du premier ou du deuxiĂšme tableau.
mesures_a = np.array([10.2, 11.5, 9.8, 12.1])
mesures_b = np.array([10.0, 11.8, 10.1, 11.9])
utiliser_a = np.array([True, False, False, True])
resultat = np.where(utiliser_a, mesures_a, mesures_b)
print(resultat)
Résultat :
[10.2 11.8 10.1 12.1]
Pour chaque position :
- si
utiliser_avautTrue, NumPy prend la valeur demesures_a; - si
utiliser_avautFalse, NumPy prend la valeur demesures_b.
np.where() vs filtre : ne pas confondreFiltre t[t > 0] : le tableau résultant est plus court (seuls les éléments qui satisfont sont conservés).
np.where() : le tableau rĂ©sultant a la mĂȘme longueur (chaque Ă©lĂ©ment reçoit une valeur selon la condition).
| Opération | Syntaxe | Description |
|---|---|---|
| Importer NumPy | import numpy as np | Convention universelle |
| Créer un masque | masque = tab_numpy > 0 | Tableau de booléens selon la condition |
| Filtrer avec un masque | tab_resultat = tab_numpy[masque] | Garde seulement les éléments qui satisfont |
| Filtrer directement | tab_resultat = tab_numpy[tab_numpy > 0] | Raccourci : filtre en une seule ligne |
| Filtre ET | tab_resultat = tab_numpy[(tab_numpy > 0) & (tab_numpy < 10)] | Les deux conditions doivent ĂȘtre vraies |
| Filtre OU | tab_resultat = tab_numpy[(tab_numpy < 0) | (tab_numpy > 10)] | Au moins une condition vraie |
| Remplacer selon condition | tab_resultat = np.where(tab_numpy < 0, 0, tab_numpy) | Si condition : met 0, sinon garde la valeur |
| Au moins un True | resultat = np.any(tab_numpy < 0) | True si au moins un élément satisfait |
| Tous True | resultat = np.all(tab_numpy > 0) | True si tous les éléments satisfont |
Les explications de cette section étaient-elles claires ?
En sciences, les donnĂ©es nâarrivent pas toujours dans le bon format. Des sĂ©ries de mesures doivent parfois ĂȘtre regroupĂ©es, des jeux de donnĂ©es provenant de sources diffĂ©rentes doivent ĂȘtre combinĂ©s, et les rĂ©sultats dâun calcul long doivent ĂȘtre conservĂ©s pour ne pas avoir Ă tout recalculer Ă chaque fois.
Cet onglet couvre les outils NumPy qui permettent de faire exactement ça : restructurer, combiner, générer et sauvegarder des tableaux.
reshape() - changer la forme sans changer les donnĂ©esreshape() rĂ©organise les Ă©lĂ©ments dâun tableau dans une nouvelle forme, sans modifier leur contenu. Câest utile quand un algorithme ou une bibliothĂšque attend des donnĂ©es dans un format prĂ©cis : par exemple, un rĂ©seau de neurones qui attend une matrice plutĂŽt quâune liste Ă plat. Le nombre total dâĂ©lĂ©ments doit rester identique.
mesures = np.arange(12) # 12 mesures en une seule ligne
print(mesures) # [ 0 1 2 3 4 5 6 7 8 9 10 11]
print(mesures.shape) # (12,)
grille = mesures.reshape(3, 4) # réorganiser en 3 séries de 4 mesures
print(grille)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(grille.shape) # (3, 4)
np.concatenate() - combiner des tableauxnp.concatenate() met plusieurs tableaux bout Ă bout pour en former un seul :
mesures_matin = np.array([36.5, 37.0, 36.8])
mesures_soir = np.array([37.2, 36.9, 37.5])
toutes_mesures = np.concatenate([mesures_matin, mesures_soir])
print(toutes_mesures) # [36.5 37. 36.8 37.2 36.9 37.5]
NumPy offre deux fonctions principales pour générer des données aléatoires :
np.random.uniform() génÚre des nombres décimaux aléatoires dans un intervalle [min, max[ :
# 5 mesures de température entre 36.0 (inclus) et 38.5 (exclus)
temperatures = np.random.uniform(36.0, 38.5, 5)
print(temperatures) # ex : [37.2 36.8 38.1 37.5 36.3]
np.random.randint() génÚre des nombres entiers aléatoires dans un intervalle [min, max[ :
# 10 valeurs de dés (entre 1 et 6 inclus)
des = np.random.randint(1, 7, 10)
print(des) # ex : [3 1 6 2 4 5 2 1 6 3]
Les fonctions alĂ©atoires donnent un rĂ©sultat diffĂ©rent chaque fois. Si l'on veut reproduire exactement le mĂȘme rĂ©sultat (pour dĂ©boguer ou tester), il faut utiliser np.random.seed(42) avant la gĂ©nĂ©ration. Le nombre entre parenthĂšses est arbitraire, câest juste un point de dĂ©part fixe pour le gĂ©nĂ©rateur de nombres alĂ©atoires.
np.save() permet de sauvegarder un tableau dans un fichier .npy, et np.load() de le recharger.
Câest utile pour conserver les rĂ©sultats dâun calcul long et les rĂ©utiliser plus tard sans tout recalculer.
# Sauvegarder
scores = np.array([85, 92, 78, 90, 88])
np.save("scores.npy", scores)
# Charger dans un autre script (ou plus tard dans le mĂȘme)
scores_charges = np.load("scores.npy")
print(scores_charges) # [85 92 78 90 88]
print(np.mean(scores_charges)) # 86.6
Le fichier scores.npy est créé dans le mĂȘme dossier que le script.
.npy nâest pas lisible dans un Ă©diteur de texteUn fichier .npy n'est pas un fichier texte, c'est un format binaire : les nombres sont stockĂ©s directement en mĂ©moire, sans conversion en texte. Cela le rend beaucoup plus rapide Ă lire et Ă Ă©crire quâun fichier texte .txt, .csv ou .json, et plus compact sur le disque. En contrepartie, son contenu apparaĂźtra comme des caractĂšres illisibles si on lâouvre dans un Ă©diteur. Câest tout Ă fait normal. Le fichier nâest pas corrompu. Il faut simplement le lire avec np.load().
Pour inspecter les donnĂ©es Ă la main ou les partager avec dâautres logiciels, mieux vaut utiliser un fichier texte .csv, .json ou .txt.
| Opération | Syntaxe | Description |
|---|---|---|
| Importer NumPy | import numpy as np | Convention universelle |
| Changer la forme | tab_resultat = tab_numpy.reshape(3, 4) | Réorganise en 3 lignes x 4 colonnes |
| Combiner des tableaux | tab_resultat = np.concatenate([tab_a, tab_b]) | Met tab_a et tab_b bout Ă bout |
| Entiers aléatoires | tab_resultat = np.random.randint(0, 10, 5) | 5 entiers aléatoires entre 0 et 9 |
| Décimaux aléatoires | tab_resultat = np.random.uniform(0, 1, 5) | 5 décimaux aléatoires entre 0 et 1 (1 exclus) |
| Sauvegarder | np.save('données.npy', tab_numpy) | Sauvegarde le tableau dans un fichier .npy |
| Charger | tab_numpy = np.load('données.npy') | Recharge le tableau depuis un fichier .npy |
Les explications de cette section étaient-elles claires ?
Matplotlib sâintĂšgre naturellement avec NumPy : on gĂ©nĂšre les donnĂ©es avec NumPy (tableaux de valeurs x et y), puis on les transmet directement Ă Matplotlib pour tracer le graphique. Ensemble, ils permettent de visualiser nâimporte quelle fonction mathĂ©matique ou jeu de donnĂ©es en quelques lignes.
linspace() â fonction â plot()Le pattern de base est toujours le mĂȘme :
- Créer un tableau de valeurs
xavecnp.linspace() - Calculer les valeurs
ycorrespondantes avec une opération vectorisée - Tracer le graphique avec
plt.plot(x, y)
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 100) # 100 points entre 0 et 10
y = np.sin(x) # calcul vectorisé : sin() sur chaque point
plt.plot(x, y)
plt.title("Fonction sinus")
plt.xlabel("x")
plt.ylabel("sin(x)")
plt.grid()
plt.show()

Les trois exemples qui suivent illustrent les cas les plus courants : tracer une fonction algĂ©brique, superposer plusieurs courbes sur le mĂȘme graphique, et tracer une courbe paramĂ©trique. Dans chaque cas, NumPy gĂ©nĂšre les tableaux x et y, et Matplotlib s'occupe de l'affichage.
GrĂące Ă la vectorisation, on peut exprimer la formule directement sur le tableau x :
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-10, 100, 1000)
y = 2 * x - 15 # opération vectorisée : appliquée à chaque élément de x
plt.plot(x, y)
plt.title("Fonction linéaire : y = 2x - 15")
plt.xlabel("x")
plt.ylabel("y")
plt.grid()
plt.show()

On peut tracer plusieurs courbes sur le mĂȘme graphique en appelant plt.plot() plusieurs fois :
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 200)
plt.plot(x, np.sin(x), label="sin(x)")
plt.plot(x, np.cos(x), label="cos(x)")
plt.plot(x, np.sin(2*x), label="sin(2x)")
plt.title("Fonctions trigonométriques")
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.grid()
plt.show()

Un cercle nâest pas le graphique dâune fonction de la forme , car une mĂȘme valeur de peut correspondre Ă deux valeurs de .
On peut toutefois le tracer avec des tableaux de coordonnées paramétriques (cos(Ξ), sin(Ξ)) :
import numpy as np
import matplotlib.pyplot as plt
angles = np.linspace(0, 2 * np.pi, 100) # 100 angles de 0 Ă 2Ï
x = np.cos(angles)
y = np.sin(angles)
plt.plot(x, y)
plt.axis("equal") # force la mĂȘme Ă©chelle sur les deux axes
plt.title("Cercle unité")
plt.grid()
plt.show()

plt.axis("equal") est essentiel ici : sans cette ligne, Matplotlib peut utiliser une Ă©chelle diffĂ©rente sur les deux axes, ce qui fait apparaĂźtre le cercle comme une ellipse. En forçant la mĂȘme Ă©chelle sur x et y, on garantit que le cercle apparaĂźt bien rond.
| Opération | Syntaxe | Description |
|---|---|---|
| Importer NumPy | import numpy as np | Convention universelle |
| Importer Matplotlib | import matplotlib.pyplot as plt | Convention universelle |
| Générer des x | x = np.linspace(0, 10, 100) | 100 points entre 0 et 10 |
| Fonction mathématique | y = np.sin(x) | Calcule y pour chaque x |
| Fonction algébrique | y = 2 * x + 3 | Opérateurs vectorisés pour y = 2x + 3 |
| Axes Ă la mĂȘme Ă©chelle | plt.axis("equal") | MĂȘme Ă©chelle sur x et y (cercle bien rond, pas une ellipse) |
Les explications de cette section étaient-elles claires ?
Pour favoriser une progression efficace, ce cours adopte une approche de classe inversée. Ce modÚle déplace l'acquisition théorique hors de la classe pour transformer les heures de rencontre en véritables séances d'application pratique.
-
Ă la maison (Exploration et Appropriation) : Vous ĂȘtes le maĂźtre de votre rythme. Ces activitĂ©s vous permettent de dĂ©couvrir les nouveaux concepts et tester les exemples au moment oĂč vous ĂȘtes le plus concentrĂ©. Si une notion vous semble obscure, n'hĂ©sitez pas Ă poser des questions Ă votre prof au fur et Ă mesure.
-
En classe (Application et Consolidation) : Le temps en prĂ©sentiel est une ressource prĂ©cieuse. Nous l'utilisons pour nous attaquer aux dĂ©fis plus complexes et aux exercices de programmation qui demandent une mobilisation active de vos connaissances. Câest le moment idĂ©al pour obtenir une rĂ©troaction immĂ©diate, collaborer avec vos pairs et bĂ©nĂ©ficier de l'accompagnement de votre enseignant au moment oĂč vous en avez le plus besoin.
- đ ActivitĂ©s Ă faire Ă la maison
- đ« ActivitĂ©s Ă faire en classe
đ§ Auto-validation des connaissancesâ
Ce formulaire sert à vérifier votre compréhension des éléments les plus importants de la rencontre R10. Ne faites ce questionnaire que lorsque vous vous sentez en trÚs bonne maßtrise de la matiÚre. En classe, dÚs votre arrivée, vous aurez un questionnaire trÚs similaire, évalué sommativement, à compléter sans accÚs à aucune documentation.
Ne pas remplir le formulaire diminue fortement vos chances de rĂ©ussir lâĂ©valuation sommative en dĂ©but de rencontre.
Assurez-vous de bien comprendre toutes les notions derriĂšre chaque question.
đš Exercices de crĂ©ationâ
Pour chacun des exercices de cette section, vous devez créer des fichiers .py avec les noms indiqués.
Pour les exercices de cette section, vous pouvez consulter librement la documentation du site web du cours.
đ CrĂ©ez un fichier r10_creer_inspecter_tableaux_numpy.py pour votre rĂ©ponse.
Un technicien en laboratoire prépare des séries de mesures. Créez les tableaux suivants dans l'ordre ci-dessous, et affichez les valeurs, le shape et le dtype de chacun. Ajoutez une ligne vide entre chaque tableau pour que l'affichage soit lisible.
- Un tableau de valeurs de pH mesurées :
[4.2, 6.8, 7.1, 5.5, 8.3] - Un tableau de 8 zéros représentant des températures initiales
- Un tableau de 5 uns représentant des facteurs de calibration
- Un tableau de 6 valeurs fixes Ă
9.81représentant la constante gravitationnelle - Un tableau de 6 positions espacées réguliÚrement entre 0 et 50 mÚtres
- Un tableau des entiers de 0 Ă 20 par pas de 2
Pour chaque tableau, l'affichage doit suivre ce format, séparé par une ligne vide :
valeurs : [4.2 6.8 7.1 5.5 8.3]
shape : (5,)
dtype : float64
valeurs : [0. 0. 0. 0. 0. 0. 0. 0.]
shape : (8,)
dtype : float64
valeurs : [1. 1. 1. 1. 1.]
shape : (5,)
dtype : float64
valeurs : [9.81 9.81 9.81 9.81 9.81 9.81]
shape : (6,)
dtype : float64
valeurs : [ 0. 10. 20. 30. 40. 50.]
shape : (6,)
dtype : float64
valeurs : [ 0 2 4 6 8 10 12 14 16 18 20]
shape : (11,)
dtype : int64
đĄ CrĂ©er une fonction pour l'affichage d'un tableau vous ferait sauver beaucoup de lignes de code!
Création de tableaux NumPy, shape, dtype
đ CrĂ©ez un fichier r10_numpy_vs_boucles.py pour votre rĂ©ponse.
Un physicien calcule la vitesse finale de 10 000 000 objets Ă l'aide de la formule
oĂč :
- m/s est la vitesse initiale (la mĂȘme pour tous les objets)
- est l'accélération propre à chaque objet (chargée depuis un fichier)
- s est le temps Ă©coulĂ© (le mĂȘme pour tous les objets)
Par exemple, pour le premier objet ( m/sÂČ) :
TĂ©lĂ©chargez le fichier accelerations.npy et placez-le dans le mĂȘme rĂ©pertoire que votre script.
accelerations.npyCe fichier pĂšse ~70 Mo et ne doit pas ĂȘtre ajoutĂ© Ă GitHub.
Ajoutez-le Ă votre .gitignore :
accelerations.npy
ou encore, pour carrément exclure tous les fichiers se terminant par .npy :
*.npy
Utilisez le code suivant pour charger les données sous deux formes :
import numpy as np
import time
accelerations_np = np.load("accelerations.npy") # tableau NumPy
accelerations_list = list(accelerations_np) # liste Python
Calcul des vitesses
- Calculez les vitesses finales avec une boucle Python (Ă partir de
accelerations_list) et mesurez le temps d'exécution avectime.time(). - Calculez les vitesses finales avec NumPy (sans boucle, à partir de
accelerations_np) et mesurez le temps d'exécution. - Avec NumPy, calculez :
- la vitesse finale minimale, maximale et moyenne parmi les 10 millions d'objets.
- les 3 premiÚres accélérations et les 3 premiÚres vitesses finales calculées.
- l'indice de la vitesse finale la plus élevée.
- Affichez les résultats en respectant le format suivant :
Temps d'exécution
- Solution avec boucle : 1.35896015 secondes
- Solution avec NumPy : 0.14341521 secondes
Statistiques sur les vitesses finales
- minimum : 6.5
- maximum : 35.0
- moyenne : 20.74975367
Détails
- Les 3 premiÚres accélérations : [4.1 9.5 7.5]
- Les 3 premiÚres vitesses finales calculées : [17.3 33.5 27.5]
- Indice de la vitesse finale la plus élevée : 531
Opérateurs arithmétiques vectorisés, NumPy vs boucles Python, fonctions d'agrégation
đ CrĂ©ez un fichier r10_oscillation_amortie.py pour votre rĂ©ponse.
Un ingénieur simule le déplacement vertical d'une bille sur un ressort selon la formule d'une oscillation amortie :
Les paramĂštres de la simulation sont les suivants :
A = 5 # amplitude
omega = 2 * np.pi # frĂ©quence angulaire (le Ï)
alpha = 0.3 # coefficient d'amortissement (le α)
Préparation des données
- Créez un tableau
tde 200 valeurs de temps entre 0 et 4 secondes. - Calculez le tableau des positions
yĂ partir de la formule ci-dessus :
Analyse des résultats
- Affichez la position maximale atteinte et la position minimale (en mĂštres).
- Affichez Ă quel indice la bille est au plus haut, ainsi que l'instant correspondant (en secondes).
Visualisation
- Tracez un graphique du déplacement
yen fonction du temps, avec un titre, des étiquettes d'axes et une grille.
Résultat attendu à la console :
Position maximale : 4.6438734623073290 m
Position minimale : -3.9969968857329263 m
Indice au plus haut : 12
Instant correspondant : 0.2412060301507538 s
Résultat attendu du graphique :

Fonctions mathématiques vectorisées, fonctions d'agrégation, opérateurs arithmétiques
đ CrĂ©ez un fichier r10_notes_etudiants.py pour votre rĂ©ponse.
Un enseignant dispose des notes de 10 étudiants (sur 100 points) :
resultats = np.array([45, 72, 38, 91, 60, 55, 83, 29, 74, 66])
à chaque étape, réalisez l'action demandée puis affichez le résultat.
Filtrage
- Créez un masque booléen identifiant les étudiants en échec (note inférieure à 60).
- Créez un tableau
notes_echeccontenant uniquement les notes des étudiants en échec. - Affichez le nombre d'étudiants en échec.
Transformation
- Créez un tableau
mentionsqui attribue automatiquement une mention à chaque étudiant :"réussite"si la note est ℠60,"échec"sinon.
Analyse
- Calculez la note moyenne, affichez-la, puis affichez combien d'étudiants sont au-dessus de la moyenne.
Résultat attendu :
Masque échec : [ True False True False False True False True False False]
Notes en échec : [45 38 55 29]
Nombre en échec : 4
Mentions : ['échec' 'réussite' 'échec' 'réussite' 'réussite' 'échec' 'réussite' 'échec' 'réussite' 'réussite']
Moyenne : 61.3
Ătudiants au-dessus de la moyenne : 5
Masques booléens, filtrage direct, transformation conditionnelle, fonctions d'agrégation
đ CrĂ©ez un fichier r10_traitement_pixels.py pour votre rĂ©ponse.
Un systÚme de traitement d'images reçoit des valeurs de pixels brutes qui peuvent dépasser les limites valides [0, 255]. Le pipeline de traitement se déroule en trois phases : d'abord détecter et corriger les valeurs invalides, puis normaliser les pixels entre 0 et 1, et enfin binariser l'image en noir et blanc.
pixels = np.array([-30, 0, 85, 128, 260, 300, 72, -5, 200, 255])
à chaque étape, réalisez l'action demandée puis affichez le résultat.
Détection et correction
- Calculez un masque booléen indiquant quelles valeurs sont hors limites (inférieures à 0 ou supérieures à 255).
- Vérifiez s'il existe au moins une valeur hors limites.
- Corrigez les pixels en forçant toute valeur infĂ©rieure Ă
0Ă0et toute valeur supĂ©rieure Ă255Ă255. - VĂ©rifiez que toutes les valeurs sont maintenant valides.
Transformation
- Ramenez les pixels dans l'intervalle
[0.0, 1.0]en divisant chaque valeur par 255 (0 reste 0, 255 devient 1.0). - Convertissez chaque pixel en noir ou blanc : les valeurs infĂ©rieures Ă
0.5deviennent0.0(noir) et les autres deviennent1.0(blanc).
Résultat attendu :
Masque hors limites : [ True False False False True True False True False False]
Au moins une hors limite : True
Pixels corrigés : [ 0 0 85 128 255 255 72 0 200 255]
Toutes les valeurs valides : True
Pixels normalisés : [0. 0. 0.3333 0.502 1. 1. 0.2824 0. 0.7843 1. ]
Pixels binarisés : [0. 0. 0. 1. 1. 1. 0. 0. 1. 1.]
Masques booléens, filtrage direct, vérification de conditions globales, encadrement de valeurs, opérateurs arithmétiques, transformation conditionnelle
đ CrĂ©ez un fichier r10_manipulation_aleatoire.py pour votre rĂ©ponse.
Un chercheur simule deux séries de mesures de pression atmosphérique (en hPa) et veut les combiner, les analyser et les sauvegarder.
à chaque étape, réalisez l'action demandée puis affichez le résultat.
Génération
- Générez une premiÚre série de 6 mesures décimales aléatoires entre 990 et 1010 à l'aide de NumPy (sans utiliser le module
randomde Python). - Générez une deuxiÚme série de 6 mesures entiÚres aléatoires entre 995 et 1005 à l'aide de NumPy.
Manipulation
- Combinez les deux séries en un seul tableau de 12 valeurs et affichez-le.
- Remplacez toutes les valeurs inférieures à 1000 par
1000.0et affichez le résultat. - Restructurez le tableau en une matrice de 3 lignes à 4 colonnes et affichez-la avec son
shape.
Les valeurs seront diffĂ©rentes Ă chaque exĂ©cution puisqu'elles sont alĂ©atoires, mais le format doit ĂȘtre identique. Exemple :
Tableau combiné : [ 997.49 1009.01 1004.64 1001.97 993.12 993.12 1005. 1005. 1002. 999. 998. 1002.]
Valeurs corrigées : [1000. 1009.01 1004.64 1001.97 1000. 1000. 1005. 1005. 1002. 1000. 1000. 1002.]
Matrice (3, 4) :
[[1000. 1009.01 1004.64 1001.97]
[1000. 1000. 1005. 1005. ]
[1002. 1000. 1000. 1002. ]]
Génération aléatoire, combinaison de tableaux, encadrement de valeurs, restructuration
đ CrĂ©ez un fichier r10_fichiers_json.py pour votre rĂ©ponse.
Un étudiant en sciences veut sauvegarder les résultats d'une expérience de laboratoire dans un fichier JSON, puis les relire pour les afficher.
Voici les données de l'expérience :
- Nom de l'expérience :
"Réaction acide-base" - Température ambiante :
22.5 - Réaction observée :
True - Mesures de pH relevées :
[4.2, 5.1, 6.7, 7.0, 6.3]
Sauvegarde
- Créez un dictionnaire Python contenant ces données.
- Sauvegardez ce dictionnaire dans un fichier
experience.jsonavec une indentation de 4.
Le fichier experience.json généré doit ressembler à :
{
"nom": "Réaction acide-base",
"temperature": 22.5,
"reaction_observee": true,
"mesures_ph": [
4.2,
5.1,
6.7,
7.0,
6.3
]
}
Lecture et affichage
- Relisez le fichier
experience.jsonet stockez son contenu dans une variable. - Affichez le nom de l'expérience, la température ambiante et la moyenne des mesures de pH.
Le résultat attendu est :
Expérience : Réaction acide-base
Température : 22.5 °C
pH moyen : 5.86
đ CrĂ©ez un fichier r10_fichiers_texte.py pour votre rĂ©ponse.
Un systÚme de capteurs enregistre des mesures de température au fil du temps. Simulez ce systÚme en trois étapes.
Ătape 1 - CrĂ©er le fichier (mode "w")
Générez 5 nombres entiers aléatoires entre -10 et 35 à l'aide de NumPy (sans utiliser le module random de Python) et
écrivez-les dans un fichier temperatures.txt, un nombre par ligne.
Ătape 2 - Ajouter des mesures (mode "a")
Générez 3 nouveaux nombres entiers aléatoires entre -10 et 35 à l'aide de NumPy et
ajoutez-les à la suite du fichier temperatures.txt, sans effacer les données existantes.
Ătape 3 - Lire et analyser (mode "r")
- Lisez toutes les lignes du fichier.
- Retirez les sauts de ligne de chaque valeur.
- Convertissez chaque valeur en entier.
- Créez un tableau NumPy à partir des valeurs lues.
- Affichez la liste complÚte des 8 températures.
- Affichez la somme des températures à l'aide de NumPy.
- Affichez la température maximale à l'aide de NumPy.
- Affichez la température minimale à l'aide de NumPy.
Les valeurs seront diffĂ©rentes Ă chaque exĂ©cution puisqu'elles sont alĂ©atoires, mais le format doit ĂȘtre identique :
Températures enregistrées : [ 3 17 -5 22 8 11 -2 30]
Somme : 84
Maximum : 30
Minimum : -5
âïž Exercices sur papierâ
Les exercices suivants ne visent pas nécessairement à pratiquer la matiÚre de cette rencontre,
mais plutÎt à vous entraßner à l'écriture de code "papier" sur des concepts plus simples, comme il pourrait y avoir à l'examen.
Faites ces exercices d'abord sur papier (ou dans un éditeur de texte simple) et sans aucune documentation, comme à l'examen.
Vous pouvez valider votre rĂ©ponse dans PyCharm Ă la fin â un luxe que vous n'aurez pas le jour de l'examen, d'oĂč l'importance de vous entraĂźner sans lui.
Sur papier, sans ordinateur, écrivez du code permettant de connaitre le nombre de valeurs supérieures à 50 dans une liste.
Prenez la liste suivante comme référence :
liste = [20, 60, 50, 10, 70, 90]
Avec ce contenu de liste, le programme devrait afficher le résultat suivant :
3
Votre programme doit fonctionner peu importe le nombre d'éléments dans la liste et quels que soient ces nombres.
đ CrĂ©ez un fichier r10_sans_pycharm_1.py pour valider votre rĂ©ponse Ă l'aide de PyCharm.
Sur papier, sans ordinateur, écrivez du code permettant de résoudre le problÚme ci-dessous.
On dispose d'une liste nommée liste contenant des tuples. Chaque tuple est composé d'une lettre et d'un nombre.
On dispose également d'une variable lettre qui contient le caractÚre à rechercher.
liste = [("a", 1), ("b", 2), ("a", 3), ("c", 4), ("b", 5)]
lettre = "a"
L'objectif est d'afficher la somme des deuxiÚme éléments de chaque tuple, mais uniquement lorsque le premier élément du tuple correspond à la valeur stockée dans la variable lettre.
Résultats attendus
Voici les résultats attendues selons différentes lettres :
- si
lettre = "a"âĄïž votre programme doit afficher :4 - si
lettre = "b"âĄïž votre programme doit afficher :7 - si
lettre = "c"âĄïž votre programme doit afficher :4 - si
lettre = "d"âĄïž votre programme doit afficher :0
Votre programme doit fonctionner correctement quelles que soient les valeurs contenues dans liste et dans lettre.
đ CrĂ©ez un fichier r10_sans_pycharm_2.py pour valider votre rĂ©ponse Ă l'aide de PyCharm.
Sur papier, sans ordinateur, tracez le graphique correspondant au code suivant le plus fidĂšlement possible. Graduez vos axes.
import matplotlib.pyplot as plt
x = [0, 1, 2, 3, 4, 5]
y = [0, 1, 4, 9, 16, 25]
plt.plot(x, y, marker='o', label='y = x^2')
plt.title("Graphique de la fonction y = x^2")
plt.xlabel("x")
plt.ylabel("y")
plt.grid()
plt.legend()
plt.show()
Une fois votre graphique tracé sur papier, validez votre réponse à l'aide de Pycharm.
Sur papier, sans ordinateur, tracez le graphique correspondant au code suivant le plus fidĂšlement possible. Graduez vos axes.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-10, 10, 100)
y = x ** 2
plt.plot(x, y, label='y = x^2')
plt.title("Graphique de la fonction y = x^2")
plt.xlabel("x")
plt.ylabel("y")
plt.grid()
plt.legend()
plt.show()
đĄ La courbe n'a pas besoin d'ĂȘtre parfaite, mais elle doit passer par des points clĂ©s.
Une fois votre graphique tracé sur papier, validez votre réponse à l'aide de Pycharm.
đŻ Solutions des exercices
Un solutionnaire possible pour chaque exercice est disponible en format vidĂ©o avec des explications. Vous pouvez vous en servir pour comparer votre solution avec une solution possible jugĂ©e optimale et vous dĂ©bloquer aprĂšs un long moment bloquĂ© sur un exercice (ex. 20 minutes) et aprĂšs avoir utilisĂ© le dĂ©bogueur pour essayer par vous-mĂȘme de trouver le problĂšme.
Il est tout Ă fait normal que certains problĂšmes demandent du temps, de la rĂ©flexion, et parfois mĂȘme un peu de frustration. Câest prĂ©cisĂ©ment dans ces moments dâeffort que lâapprentissage sâancre rĂ©ellement.
Consulter un solutionnaire avant dâavoir tentĂ© lâexercice par soi-mĂȘme, ou le parcourir trop rapidement, revient Ă court-circuiter le processus dâapprentissage. Ce nâest pas simplement contre-productif, câest pĂ©dagogiquement dĂ©sastreux.
En sautant lâĂ©tape de la rĂ©flexion personnelle, on prive son cerveau de lâoccasion de construire des connexions durables. Et Ă force de rĂ©pĂ©ter ce rĂ©flexe, on risque de passer Ă cĂŽtĂ© des compĂ©tences essentielles, ce qui peut mener Ă des Ă©checs plus tard, mĂȘme si tout semble facile sur le moment. Alors oui, prenez le temps. Lâerreur fait partie du jeu. Câest en cherchant, en tĂątonnant, en doutant, quâon devient rĂ©ellement compĂ©tent. Le solutionnaire doit ĂȘtre un outil de validation, pas un raccourci.
đš Solution des exercices de crĂ©ation :
- Créer et inspecter des tableaux
- NumPy vs boucles
- Oscillation amortie
- Notes d'étudiants
- Traitement des pixels
- Manipulation et aléatoire
- Fichier JSON
- Fichiers texte
âïž Solution des exercices sur papier :