TP 4#
Objectifs#
Travail sur les fonctions Python intégrées#
map()
filter()
reduce()
Multiprocessus#
multiprocessing.cpu_count
multiprocessing.Pool
map
Exercice 1 [★]#
Dans cet exercice, nous allons examiner la fonction intégrée de Python appelée filter() qui peut être utilisée pour sélectionner les éléments d’une collection correspondant à une condition particulière.
# Initialization
num = [i for i in range(1, 20)]
print(num)
Nous utiliserons la documentation disponible pour les différentes fonctions. Dans ce but, nous utiliserons un point d’interrogation (?) après le nom de la fonction ou d’une classe comme indiqué ci-dessous.
?filter
La fonction filter(function, iterable)
prend deux paramètres : une fonction et un itérable. La fonction agit sur chaque élément d’un type de données itérable.
Dans le premier exemple, nous utilisons None
comme premier paramètre. Dans ce cas, le filtre agira comme une fonction d’identité et retournera l’itérable.
# Use of filter function with None as the first parameter
num = [i for i in range(1, 20)]
filtered = list(filter(None, num))
print(filtered)
Dans l’exemple suivant, nous allons filtrer les nombres pairs de la liste d’entrée.
Notez que nous avons écrit une fonction even() qui renvoie True
si le nombre d’entrée est pair,
sinon False
.
filer()
retournera les éléments de la liste qui ont retourné True
lorsqu’ils ont été passés comme argument à la fonction even().
def even(item):
if item % 2 == 0:
return True
return False
num = [i for i in range(1, 20)]
filtered = list(filter(even, num))
print(filtered)
Dans l’exemple suivant, nous avons une nouvelle fonction odd()
qui renvoie True
lorsque le nombre en entrée est impair.
Nous utilisons cette nouvelle fonction comme entrée de la fonction filter()
.
def odd(item):
if item % 2 == 0:
return False
return True
num = [i for i in range(1, 20)]
filtered = list(filter(odd, num))
print(filtered)
Question Écrivez un programme utilisant filter() qui prend une liste de chaînes de caractères et filtre les palindromes.
Filtrage avec des structures imbriquées#
La fonction filter()
peut également être appliquée à des structures de données complexes comme des listes de dictionnaires ou de tuples.
On vous donne une liste de dictionnaires représentant des employés, chacun ayant les clés name
, age
et department
:
employees = [
{"name": "Alice", "age": 28, "department": "HR"},
{"name": "Bob", "age": 35, "department": "Engineering"},
{"name": "Charlie", "age": 22, "department": "Marketing"},
{"name": "David", "age": 45, "department": "Engineering"},
{"name": "Pierre", "age": 29, "department": "HR"}
]
Questions
Filtrage par département : Écrivez un programme qui utilise
filter()
pour créer une liste d’employés qui travaillent dans le département “Engineering”.Filtrage par tranche d’âge : Écrivez un programme qui utilise
filter()
pour trouver les employés dont l’âge est compris entre 25 et 40 ans (inclus).Filtrage par longueur de nom : Écrivez un programme qui utilise
filter()
pour trouver les employés dont le nom contient plus de 3 caractères.
Filtrage avancé de chaînes de caractères#
On vous donne une liste de phrases. Votre tâche est de filtrer les phrases en fonction de diverses conditions.
sentences = [
"Bienvenue dans le monde de la programmation!",
"Le débogage fait partie du jeu.",
"La pratique rend parfait, alors continue à coder.",
"Les algorithmes d'apprentissage automatique sont de plus en plus puissants.",
"La visualisation de données est un moyen de communiquer des informations complexes.",
"Les données non structurées sont un défi pour les Data Scientists."
]
Questions
Filtrage par longueur : Écrivez un programme qui utilise
filter()
pour sélectionner les phrases comportant moins de 5 mots.Filtrage par mots-clés : Écrivez un programme qui utilise
filter()
pour sélectionner les phrases contenant le mot “coder”.Filtrage par mots palindromiques : Écrivez un programme qui utilise
filter()
pour sélectionner les phrases contenant au moins un palindrome.
Exercice 2 [★]#
Que faire si nous voulons appliquer la même fonction sur plusieurs éléments d’une liste.
Prenons l’exemple suivant : supposons que nous ayons une fonction qui puisse retourner le carré d’un nombre. Nous voulons maintenant appliquer cette fonction à tous les nombres d’une liste. Nous pouvons écrire un programme avec une boucle pour y parvenir. Mais nous allons écrire un programme plus petit pour y parvenir.
\(f(x) = x ^ 2\)
\(g([a,b,...]) = [f(a), f(b), ..]\)
\(g([a,b,...]) = [a^2, b^2, ..]\)
Python fournit une autre fonction intégrée appelée map(function, iterable, ...)
.
?map
def square(item):
return item * item
num = [i for i in range(1, 20)]
squared = list(map(square, num))
print(filtered)
Mais que faire si notre programme prend plusieurs entrées.
L’exemple suivant montre ce cas. La fonction product()
prend deux nombres en entrée et renvoie leur produit.
def product(item1, item2):
return item1 * item2
num1 = [i for i in range(1, 20)]
print(num1)
num2 = [i for i in range(10, 20)]
print(num2)
product_value = list(map(product, num1, num2))
print(filtered)
Enfin, nous examinons une autre fonction appelée reduce() qui applique une fonction de deux arguments de manière cumulative sur les membres de la liste, de gauche à droite.
\(f(x) = x ^ 2\)
\(g([a,b,...]) = [f(a), f(b), ..]\)
\(g([a,b,...]) = [a^2, b^2, ..]\)
\(h(g([a,b,c,..])) = (((a^2 + b^2) + c^2) + ...) \)
from functools import reduce
?reduce
Dans l’exemple suivant, nous calculons la somme des membres d’une liste.
Nous passons la fonction sum_num() comme premier argument à la fonction reduce. sum_num() prend deux nombres en entrée et renvoie leur nombre.
from functools import reduce
import random
def sum_num(item1, item2):
return item1 + item2
num = [i for i in range(1, 20)]
print(num)
sum_value = reduce(sum_num, num)
print(sum_value)
Dans l’exemple suivant, nous utilisons la même fonction sum_num(), mais sur des nombres réels.
num = [random.uniform(0, i) for i in range(1, 20)]
print(num)
sum_value = reduce(sum_num, num)
print(sum_value)
Dans l’exemple suivant, nous utilisons une autre fonction product().
from functools import reduce
def product(item1, item2):
return item1 * item2
num = [i for i in range(1, 20)]
print(num)
sum_num = reduce(product, num)
print(sum_num)
Question: Écrivez un programme qui prend une liste de matrices de taille 2x2 et calcule la somme de toutes les matrices.
Opérations sur les matrices avec map()
et reduce()
#
On vous donne une liste de matrices 2x2 (listes de listes). Vous devez appliquer diverses opérations en utilisant map()
et reduce()
.
from functools import reduce
matrices = [
[[1, 2], [3, 4]],
[[0, 1], [2, 3]],
[[-1, -2], [-3, -4]],
[[5, 6], [7, 8]]
]
Questions
Somme de toutes les matrices : Écrivez un programme qui utilise
reduce()
pour calculer la somme de toutes les matrices.Multiplication élément par élément : Écrivez un programme qui utilise
map()
pour calculer la multiplication élément par élément de deux matrices.Filtrage de matrices : Écrivez un programme qui utilise
filter()
pour sélectionner uniquement les matrices dont tous les éléments sont positifs.
Transformation et agrégation de données#
Vous disposez d’une liste de dictionnaires représentant des produits, avec les clés name
, price
et quantity
.
from functools import reduce
products = [
{"name": "Laptop", "price": 1200, "quantity": 3},
{"name": "Smartphone", "price": 800, "quantity": 5},
{"name": "Tablet", "price": 300, "quantity": 10},
{"name": "Smartwatch", "price": 200, "quantity": 15}
]
Questions
Valeur totale de l’inventaire : Écrivez un programme qui utilise
map()
etreduce()
pour calculer la valeur totale de tous les produits en stock.Filtrage par prix : Écrivez un programme qui utilise
filter()
pour trouver les produits dont le prix est supérieur à un certain seuil (par exemple, 500).Application d’une remise : Écrivez un programme qui utilise
map()
pour appliquer une remise de 10 % à tous les produits et renvoie la liste mise à jour.
Exercice 3 [★★]#
Dans les exemples suivants, nous utilisons des expressions lambda et les passons comme arguments aux fonctions filter(), map(), et reduce().
Dans l’exemple suivant, l’expression lambda lambda x : x%2
prend x en entrée et retourne la valeur de x%2
. Cette approche est similaire à celle que nous avons vue ci-dessus avec la fonction even().
num = [i for i in range(1, 20)]
filtered = list(filter(lambda x: x % 2 == 0, num))
print(filtered)
Dans l’exemple suivant, nous prenons l’exemple avec la fonction odd() et le remplaçons par une expression lambda.
num = [i for i in range(1, 20)]
filtered = list(filter(lambda x: x % 2 != 0, num))
print(filtered)
Dans l’exemple suivant, nous prenons l’exemple avec la fonction square() et le remplaçons par une expression lambda.
num = [i for i in range(1, 20)]
squared = list(map(lambda x: x * 2, num))
print(squared)
Et si nous voulons passer deux arguments, comme dans l’exemple product() ci-dessus.
num1 = [i for i in range(1, 20)]
print(num1)
num2 = [i for i in range(10, 20)]
print(num2)
product = list(map(lambda x, y: x * y, num1, num2))
print(product)
Dans les exemples suivants, nous utilisons l’expression lambda avec la fonction reduce().
from functools import reduce
import random
num = [i for i in range(1, 20)]
print(num)
sum_value = reduce(lambda x, y: x + y, num)
print(sum_value)
Comme dans l’exemple avec sum_num(), nous testons des nombres réels avec les expressions lambda.
from functools import reduce
import random
num = [i for i in range(1, 20)]
print(num)
sum_value = reduce(lambda x, y: x + y, num)
print(sum_value)
Maintenant, nous remplaçons le produit() par une expression lambda.
from functools import reduce
import random
num = [i for i in range(1, 20)]
print(num)
product_value = reduce(lambda x, y: x * y, num)
print(product_value)
Question Écrivez un programme utilisant map(), reduce() et des expressions lambda pour compter la longueur totale de toutes les chaînes de caractères dans une liste.
Analyse de texte avec des expressions lambda#
Vous disposez d’une liste de phrases. Chaque phrase est une chaîne de caractères contenant plusieurs mots.
Utilisez map()
, filter()
et reduce()
avec des expressions lambda pour analyser le texte.
sentences = [
"Bienvenue dans le monde de la programmation!",
"Le débogage fait partie du jeu.",
"La pratique rend parfait, alors continue à coder.",
"Les algorithmes d'apprentissage automatique sont de plus en plus puissants.",
"La visualisation de données est un moyen de communiquer des informations complexes.",
"Les données non structurées sont un défi pour les Data Scientists."
]
Questions
Compte des mots : Écrivez un programme qui utilise
map()
etreduce()
pour compter le nombre total de mots dans toutes les phrases.Phrase la plus longue : Écrivez un programme qui utilise
reduce()
pour trouver la phrase la plus longue en nombre de mots.Filtrage des phrases courtes : Écrivez un programme qui utilise
filter()
pour ne conserver que les phrases contenant plus de 6 mots.
Traitement de données financières avec des expressions lambda#
Vous disposez d’une liste de transactions représentées par des dictionnaires.
Utilisez map()
, filter()
et reduce()
avec des expressions lambda pour traiter les données.
from functools import reduce
transactions = [
{"date": "2025-03-10", "type": "income", "amount": 1200},
{"date": "2025-03-11", "type": "expense", "amount": 400},
{"date": "2025-03-12", "type": "income", "amount": 1500},
{"date": "2025-03-13", "type": "expense", "amount": 800},
{"date": "2025-03-14", "type": "income", "amount": 2000},
{"date": "2025-03-15", "type": "expense", "amount": 500},
{"date": "2025-03-16", "type": "income", "amount": 1800},
]
Questions
Calcul du solde net : Écrivez un programme qui utilise
reduce()
pour calculer le solde net (somme de tous les revenus moins la somme de toutes les dépenses).Filtrage des transactions : Écrivez un programme qui utilise
filter()
pour récupérer uniquement les transactions de type revenu supérieures à un certain seuil (par exemple, 1500).Montants des transactions : Écrivez un programme qui utilise
map()
pour extraire uniquement les montants des transactions et les renvoyer sous forme de liste.
Exercice 4 [★★★]#
Nous voulons utiliser le multitraitement pour calculer les valeurs en parallèle. Pour ce faire, nous utiliserons le paquet multiprocessing.
D’abord nous trouvons le nombre de processeurs dans notre machine..
import multiprocessing as mp
?mp.cpu_count
import multiprocessing as mp
print(mp.cpu_count())
Ensuite, nous allons créer un pool de processus pour le calcul et nous utilisons la méthode Pool().
import multiprocessing as mp
?mp.Pool
Dans l’exemple suivant, nous créons un pool dont le nombre de processus est égal au nombre de processeurs de notre machine.
Regardez comment nous transformons notre exemple précédent de map-reduce dans le contexte du multiprocessus.
from functools import reduce
import multiprocessing as mp
cpu_count = mp.cpu_count()
def squared(x):
return x * x
num = [i for i in range(1, 20)]
with mp.Pool(processes=cpu_count) as pool:
list_squared = pool.map(squared, num)
print(list_squared)
product_value = reduce(lambda x, y: x * y, list_squared)
print(product_value)
Dans l’exemple suivant, nous voulons télécharger un certain nombre de pages en parallèle. Nous passons la fonction download_page() comme entrée à la fonction pool.map(). Le but de la fonction est de télécharger les pages de Wikidata. Vérifiez le résultat du code suivant.
Changez le nombre de processus et testez le résultat.
import requests
def download_page(item):
r = requests.get(
"https://www.wikidata.org/wiki/Special:EntityData/" + item + ".json"
)
# success
if r.status_code == 200:
with open(item + ".json", "w") as w:
w.write(str(r.json()))
w.close()
return r.status_code
process_count = 2
pages = ["Q1", "Q2", "Q3", "Q4", "Q5", "Q6"]
with mp.Pool(processes=process_count) as pool:
status = pool.map(download_page, pages)
print(status)
Maintenant, nous voulons analyser les pages téléchargées. Dans l’exemple suivant, nous comptons le nombre d’URLs contenant “wikipedia.org”.
import os
def analyse_file(filename):
with open(filename, "r") as w:
data = w.read()
tokens = data.split(",")
urls = list(filter(lambda w: "wikipedia.org" in w, tokens))
return len(urls)
return 0
files = os.listdir(".")
json_files = list(filter(lambda f: ".json" in f, files))
with mp.Pool(processes=cpu_count) as pool:
counts = pool.map(analyse_file, json_files)
print(counts)
total_count = reduce(lambda x, y: x + y, counts)
print(total_count)
Question: Écrivez un programme qui interroge Wikidata pour obtenir 100 URL d’images de villes et qui télécharge les images sur votre machine en utilisant multiprocessing et map(). Le programme doit ensuite analyser chaque image téléchargée et trouver les deux couleurs prédominantes de chaque image, toujours en utilisant multiprocessing et map().
Traitement de données en parallèle avec Multiprocessing#
Question
Écrivez un programme qui prend une liste d’URLs pointant vers des fichiers texte hébergés en ligne.
Téléchargez tous les fichiers texte de manière concurrente en utilisant
multiprocessing.Pool()
etmap()
.Une fois les fichiers téléchargés, effectuez les tâches suivantes en parallèle :
Compter le nombre total de mots dans chaque fichier.
Compter la fréquence de chaque mot dans l’ensemble des fichiers (sans distinction de casse).
Agrégez les résultats et affichez les 10 mots les plus courants ainsi que leurs fréquences.
Remarque : Utilisez multiprocessing.Pool()
et map()
pour le traitement.
Analyse d’images avec Multiprocessing#
Question
Écrivez un programme qui prend une liste de chemins de fichiers d’images et les traite de manière concurrente pour effectuer les tâches suivantes :
Redimensionner toutes les images à une résolution fixe (par exemple, 128x128).
Convertir les images en niveaux de gris et calculer leur intensité moyenne.
Générer des miniatures pour toutes les images et les enregistrer dans un répertoire spécifié.
Agréger les résultats et afficher :
L’image avec l’intensité moyenne la plus élevée.
L’image avec l’intensité moyenne la plus faible.
Remarque : Utilisez multiprocessing.Pool()
et map()
pour le traitement.