Calcul des moyennes par tag d'un settag (avec les tenseurs)

This commit is contained in:
Cléo Baras 2024-01-21 18:05:00 +01:00
parent 7a0b560d54
commit 340aa749b2

View File

@ -35,6 +35,7 @@ Created on Fri Sep 9 09:15:05 2016
@author: barasc @author: barasc
""" """
from app.comp import moy_sem
from app.comp.res_sem import load_formsemestre_results from app.comp.res_sem import load_formsemestre_results
from app.models import FormSemestre from app.models import FormSemestre
from app.pe.pe_semestretag import SemestreTag from app.pe.pe_semestretag import SemestreTag
@ -92,12 +93,26 @@ class SetTag(pe_tagtable.TableTag):
self.tags_sorted = self.do_taglist() self.tags_sorted = self.do_taglist()
"""Construit le cube de notes""" """Construit le cube de notes"""
self.notes_cube = {} self.notes_cube = self.compute_notes_cube()
"""Les moyennes par tag""" """Calcul les moyennes par tag sous forme d'un dataframe"""
etudids = self.get_etudids()
self.notes = compute_tag_moy(self.notes_cube, etudids, self.tags_sorted)
"""Synthétise les moyennes/classements par tag"""
self.moyennes_tags = {} self.moyennes_tags = {}
for tag in self.tags_sorted:
moy_gen_tag = self.notes[tag]
class_gen_tag = moy_sem.comp_ranks_series(moy_gen_tag)[1] # en int
self.moyennes_tags[tag] = {
"notes": moy_gen_tag,
"classements": class_gen_tag,
"min": moy_gen_tag.min(),
"max": moy_gen_tag.max(),
"moy": moy_gen_tag.mean(),
"nb_inscrits": len(moy_gen_tag),
}
# -------------------------------------------------------------------------------------------------------------------
def compute_notes_cube(self): def compute_notes_cube(self):
"""Construit le cube de notes (etudid x tags x semestre_aggregé) """Construit le cube de notes (etudid x tags x semestre_aggregé)
nécessaire au calcul des moyennes de l'aggrégat nécessaire au calcul des moyennes de l'aggrégat
@ -115,7 +130,7 @@ class SetTag(pe_tagtable.TableTag):
for frmsem_id in semestres_id: for frmsem_id in semestres_id:
"""Partant d'un dataframe vierge""" """Partant d'un dataframe vierge"""
df = pd.DataFrame(np.nan, index=etudids, columns=self.tags_sorted) df = pd.DataFrame(np.nan, index=etudids, columns=tags)
"""Charge les notes du semestre tag""" """Charge les notes du semestre tag"""
notes = self.semestres_tags_aggreges[frmsem_id].notes notes = self.semestres_tags_aggreges[frmsem_id].notes
@ -138,11 +153,8 @@ class SetTag(pe_tagtable.TableTag):
return etudids_x_tags_x_semestres return etudids_x_tags_x_semestres
# -------------------------------------------------------------------------------------------------------------------
def get_etudids(self): def get_etudids(self):
return list(self.identdict.keys()) return list(self.etudiants.keys())
# ------------------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------------------------
def do_taglist(self): def do_taglist(self):
@ -156,68 +168,6 @@ class SetTag(pe_tagtable.TableTag):
tags.extend(self.semestres_tags_aggreges[frmsem_id].tags_sorted) tags.extend(self.semestres_tags_aggreges[frmsem_id].tags_sorted)
return sorted(set(tags)) return sorted(set(tags))
# -------------------------------------------------------------------------------------------------------------------
def do_tagdict(self):
"""Synthétise la liste des modules pris en compte dans le calcul d'un tag (pour analyse des résultats)"""
self.tagdict = {}
for semtag in self.SemTagDict.values():
for tag in semtag.get_all_tags():
if tag != "but":
if tag not in self.tagdict:
self.tagdict[tag] = {}
for mod in semtag.tagdict[tag]:
self.tagdict[tag][mod] = semtag.tagdict[tag][mod]
# -------------------------------------------------------------------------------------------------------------------
def get_NotesEtCoeffsSetTagEtudiant(self, tag, etudid):
"""Récupère tous les notes et les coeffs d'un étudiant relatives à un tag dans ses semestres valides et les renvoie dans un tuple (notes, coeffs)
avec notes et coeffs deux listes"""
lesSemsDeLEtudiant = [
self.parcoursDict[etudid][nom_sem] for nom_sem in self.parcours
] # peuvent être None
notes = [
self.SemTagDict[fid].get_moy_from_resultats(tag, etudid)
for fid in lesSemsDeLEtudiant
if tag in self.SemTagDict[fid].taglist
] # eventuellement None
coeffs = [
self.SemTagDict[fid].get_coeff_from_resultats(tag, etudid)
for fid in lesSemsDeLEtudiant
if tag in self.SemTagDict[fid].taglist
]
return (notes, coeffs)
# -------------------------------------------------------------------------------------------------------------------
def comp_MoyennesSetTag(self, tag, force=False):
"""Calcule et renvoie les "moyennes" des étudiants à un tag donné, en prenant en compte tous les semestres taggués
de l'aggrégat, et leur coeff Par moyenne, s'entend une note moyenne, la somme des coefficients de pondération
appliqué dans cette moyenne.
Force ou non le calcul de la moyenne lorsque des notes sont manquantes.
Renvoie les informations sous la forme d'une liste [etudid: (moy, somme_coeff_normalisée, rang), ...}
"""
# if tag not in self.get_all_tags() : return None
# Calcule les moyennes
lesMoyennes = []
for (
etudid
) in (
self.get_etudids()
): # Pour tous les étudiants non défaillants du semestre inscrits dans des modules relatifs au tag
(notes, coeffs_norm) = self.get_NotesEtCoeffsSetTagEtudiant(
tag, etudid
) # lecture des notes associées au tag
(moyenne, somme_coeffs) = pe_tagtable.moyenne_ponderee_terme_a_terme(
notes, coeffs_norm, force=force
)
lesMoyennes += [
(moyenne, somme_coeffs, etudid)
] # Un tuple (pour classement résumant les données)
return lesMoyennes
class SetTagInterClasse(pe_tagtable.TableTag): class SetTagInterClasse(pe_tagtable.TableTag):
"""Récupère les moyennes de SetTag aggrégeant un même parcours (par ex un ['S1', 'S2'] n'ayant pas fini au même S2 """Récupère les moyennes de SetTag aggrégeant un même parcours (par ex un ['S1', 'S2'] n'ayant pas fini au même S2
@ -339,3 +289,43 @@ class SetTagInterClasse(pe_tagtable.TableTag):
(moyenne, somme_coeffs, etudid) (moyenne, somme_coeffs, etudid)
] # Un tuple (pour classement résumant les données) ] # Un tuple (pour classement résumant les données)
return lesMoyennes return lesMoyennes
def compute_tag_moy(set_cube: np.array, etudids: list, tags: list):
"""Calcul de la moyenne par tag sur plusieurs semestres.
La moyenne est un nombre (note/20), ou NaN si pas de notes disponibles
*Remarque* : Adaptation de moy_ue.compute_ue_moys_apc au cas des moyennes de tag
par aggrégat de plusieurs semestres.
Args:
set_cube: notes moyennes aux modules ndarray
(etuds x modimpls x UEs), des floats avec des NaN
etudids: liste des étudiants (dim. 0 du cube)
tags: liste des tags (dim. 1 du cube)
Returns:
Un DataFrame avec pour columns les moyennes par tags,
et pour rows les etudid
"""
nb_etuds, nb_tags, nb_semestres = set_cube.shape
assert nb_etuds == len(etudids)
assert nb_tags == len(tags)
# Quelles entrées du cube contiennent des notes ?
mask = ~np.isnan(set_cube)
# Enlève les NaN du cube pour les entrées manquantes
set_cube_no_nan = np.nan_to_num(set_cube, nan=0.0)
# Les moyennes par tag
with np.errstate(invalid="ignore"): # ignore les 0/0 (-> NaN)
etud_moy_tag = np.sum(set_cube_no_nan, axis=2) / np.sum(mask, axis=2)
# Le dataFrame
etud_moy_tag_df = pd.DataFrame(
etud_moy_tag,
index=etudids, # les etudids
columns=tags, # les tags
)
return etud_moy_tag_df