M55 - Data Science & Scientific Computing 5
  1.   Exercices
  2. Notes L3 Math
  • M55 - Data Science and Scientific Computing 5

  • Syllabus

  •   Cours
    • Introduction
    • Series
    • Data Frames
    • Une analyse complète : le Titanic

  •   Exercices
    • Premières manipulations
    • Notes L3 Math
    • Population France
    • Netflix User
    • Presidentielles USA 2016

  •   Fichiers sources

Contenu de la page

  • 1 Exercice
    • 1.1 Semestre 1
    • 1.2 Semestre 2
    • 1.3 Calculs à effectuer à partir des deux DataFrames
  1.   Exercices
  2. Notes L3 Math

Notes et moyennes pondérées en L3 Mathématiques

Auteur·rice

Gloria FACCANONI

Date de publication

24 novembre 2025

1 Exercice

On s’intéresse aux résultats d’un étudiant (ou de deux étudiants) en L3 Mathématiques, pour les deux semestres de l’année universitaire.

On vous fournit les ECUE, leurs coefficients, et les notes (aléatoires) de chaque étudiant.

1.1 Semestre 1

  • Créér une Series contenant les coefficients des ECUE. Les indices doivent être les noms des ECUE.
  • Crééer une Series contenant les notes des ECUE (entiers aléatoires entre 0 et 20), avec les mêmes indices que pour les coefficients.
  • Construire un DataFrame à partir de ces deux Series.

Exemple attendu :

Bonus: ajouter un deuxième étudiant.

1.2 Semestre 2

Faire la même chose pour les ECUE du semestre 2.

Exemple attendu :

Bonus: ajouter un deuxième étudiant.

1.3 Calculs à effectuer à partir des deux DataFrames

  • Calculer la moyenne pondérée du semestre 1 : \[ \bar{x} = \frac{\sum_i \text{note}_i \times \text{coeff}_i}{\sum_i \text{coeff}_i} \]

  • Calculer la moyenne pondérée du semestre 2

  • Fusionner les deux DataFrames (par concaténation) puis calculer la moyenne pondérée globale. Exemple attendu :

  • Pour chaque étudiant, déterminer l’ECUE où il a eu sa pire note et l’ECUE où il a eu sa meilleure note.

import pandas as pd
import numpy as np
# --- Semestre 1 : définition des ECUE, coefficients, et notes des étudiants ---

# Liste des ECUE du semestre 1
ecue_names_semester1 = [
    "M51 Intégration",
    "M52 Topologie",
    "M53 Calcul différentiel",
    "M54 Algèbre 5",
    "M55 DS&SC 5",
    "RDOC",
    "PPE"
]

nb_ecue_semester1 = len(ecue_names_semester1)

# Coefficients des ECUE (indexés par les noms des ECUE)
coefficients_semester1 = pd.Series(
    [8, 8, 8, 4, 2, 0, 0],
    index=ecue_names_semester1
)

# Notes aléatoires pour deux étudiants
etu_1_semester1 = pd.Series(
    np.random.randint(0, 21, size=nb_ecue_semester1),
    index=ecue_names_semester1
)

etu_2_semester1 = pd.Series(
    np.random.randint(0, 21, size=nb_ecue_semester1),
    index=ecue_names_semester1
)

# Construction du DataFrame
df_semester1 = pd.DataFrame({
    "Coefficients": coefficients_semester1,
    "Étudiant 1": etu_1_semester1,
    "Étudiant 2": etu_2_semester1
})

display(df_semester1)
Coefficients Étudiant 1 Étudiant 2
M51 Intégration 8 1 8
M52 Topologie 8 7 17
M53 Calcul différentiel 8 0 5
M54 Algèbre 5 4 10 10
M55 DS&SC 5 2 16 15
RDOC 0 4 6
PPE 0 3 9
# --- Semestre 2 : définition des ECUE, coefficients, et notes des étudiants ---

# Liste des ECUE du semestre 2
ecue_names_semester2 = [
    "M61 EDO",
    "M62 Analyse Complexe",
    "M63 Modélisation",
    "M64 DS&SC 6",
    "UE65",
    "UE66"
]

nb_ecue_semester2 = len(ecue_names_semester2)

# Coefficients des ECUE (indexés par les noms des ECUE)
coefficients_semester2 = pd.Series(
    [5, 9, 4, 4, 6, 2],
    index=ecue_names_semester2
)

# Notes aléatoires pour deux étudiants
etu_1_semester2 = pd.Series(
    np.random.randint(0, 21, size=nb_ecue_semester2),
    index=ecue_names_semester2
)

etu_2_semester2 = pd.Series(
    np.random.randint(0, 21, size=nb_ecue_semester2),
    index=ecue_names_semester2
)

# Construction du DataFrame
df_semester2 = pd.DataFrame({
    "Coefficients": coefficients_semester2,
    "Étudiant 1": etu_1_semester2,
    "Étudiant 2": etu_2_semester2
})

display(df_semester2)
Coefficients Étudiant 1 Étudiant 2
M61 EDO 5 2 19
M62 Analyse Complexe 9 2 12
M63 Modélisation 4 1 11
M64 DS&SC 6 4 4 18
UE65 6 15 20
UE66 2 9 16
# Calcul de la moyenne pondérée pour un étudiant donné au semestre 1

# df_semester1["Étudiant 1"].mean()  
# Non pertinent : cette moyenne n'est pas pondérée, 
# donc elle donne le même poids à un ECUE coefficient 8 qu'à un ECUE coefficient 0.
# Fonction qui pour un DataFrame donné et un étudiant donné 
# calcule la moyenne pondérée

def weighted_average(df, student_name):
    notes = df[student_name]
    coeffs = df["Coefficients"]
    
    # --- Somme pondérée ---
    return (notes * coeffs).sum() / coeffs.sum()
    
    # --- Alternatives  ---
    # return notes.dot(coeffs) / coeffs.sum()
    # return np.average(notes, weights=coeffs)
# Moyenne pondérée pour chaque étudiant au semestre 1
print("Semestre 1")
for etu in ["Étudiant 1", "Étudiant 2"]:
    print(f"{etu} : {weighted_average(df_semester1, etu):.2f}")
Semestre 1
Étudiant 1 : 4.53
Étudiant 2 : 10.33
# Moyenne pondérée pour chaque étudiant au semestre 2
print("Semestre 2")
for etu in ["Étudiant 1", "Étudiant 2"]:
    print(f"{etu} : {weighted_average(df_semester2, etu):.2f}")
Semestre 2
Étudiant 1 : 7.20
Étudiant 2 : 3.37

Notes et coefficients pour l’année entière :

# ==========================================
# Fusion des semestres pour l'année entière
# ==========================================

# Option 1 : concaténation simple (les lignes sont juste empilées)
df_year = pd.concat([df_semester1, df_semester2])
display(df_year)

# Option 2 : concaténation avec MultiIndex pour identifier le semestre
# df_year = pd.concat([df_semester1, df_semester2], 
#                     keys=["Semestre 1", "Semestre 2"], axis=0)
# display(df_year)

# Avantages :
# - Option 1 : plus simple pour calculer directement les moyennes pondérées
# - Option 2 : permet de conserver l'information du semestre dans l'index
Coefficients Étudiant 1 Étudiant 2
M51 Intégration 8 8 18
M52 Topologie 8 15 12
M53 Calcul différentiel 8 8 0
M54 Algèbre 5 4 18 10
M55 DS&SC 5 2 14 9
RDOC 0 15 6
PPE 0 11 2
M61 EDO 5 0 2
M62 Analyse Complexe 9 12 1
M63 Modélisation 4 0 13
M64 DS&SC 6 4 7 1
UE65 6 8 4
UE66 2 16 1
# Calculs de la pire et meilleure note pour chaque étudiant au semestre 1 

for etu in ["Étudiant 1", "Étudiant 2"]:
    min_idx = df_semester1[etu].idxmin()
    max_idx = df_semester1[etu].idxmax()
    print(f"{etu} :")
    print(f"  Pire note au semestre 1 : {df_semester1.loc[min_idx, etu]} à {min_idx}")
    print(f"  Meilleure note au semestre 1 : {df_semester1.loc[max_idx, etu]} à {max_idx}")
    print()
Étudiant 1 :
  Pire note au semestre 1 : 8 à M51 Intégration
  Meilleure note au semestre 1 : 18 à M54 Algèbre 5

Étudiant 2 :
  Pire note au semestre 1 : 0 à M53 Calcul différentiel
  Meilleure note au semestre 1 : 18 à M51 Intégration
# ===============================
# DataFrame récapitulatif annuel
# ===============================

students = ["Étudiant 1", "Étudiant 2"]

df_summary = pd.DataFrame({
    etu: {
        "Pire note": df_year[etu].min(),
        "ECUE pire note": df_year[etu].idxmin(),
        "Meilleure note": df_year[etu].max(),
        "ECUE meilleure note": df_year[etu].idxmax(),
        "Moyenne annuelle pondérée": weighted_average(df_year, etu),
        "Moyenne semestre 1": weighted_average(df_semester1, etu),
        "Moyenne semestre 2": weighted_average(df_semester2, etu)
    } 
    for etu in students
})

display(df_summary)
Étudiant 1 Étudiant 2
Pire note 0 0
ECUE pire note M61 EDO M53 Calcul différentiel
Meilleure note 18 18
ECUE meilleure note M54 Algèbre 5 M51 Intégration
Moyenne annuelle pondérée 9.4 6.65
Moyenne semestre 1 11.6 9.933333
Moyenne semestre 2 7.2 3.366667
Retour au sommet
Premières manipulations
Population France

© Copyright 2024, Gloria Faccanoni

 

This page is built with ❤️ and Quarto.