forked from ScoDoc/ScoDoc
Optimize compute_module_moy
This commit is contained in:
parent
83ba9cf186
commit
5a3c25e67f
@ -121,8 +121,8 @@ def df_load_modimpl_notes(moduleimpl_id: int) -> pd.DataFrame:
|
|||||||
|
|
||||||
|
|
||||||
def compute_module_moy(
|
def compute_module_moy(
|
||||||
evals_notes: pd.DataFrame,
|
evals_notes_df: pd.DataFrame,
|
||||||
evals_poids: pd.DataFrame,
|
evals_poids_df: pd.DataFrame,
|
||||||
evaluations: list,
|
evaluations: list,
|
||||||
) -> pd.DataFrame:
|
) -> pd.DataFrame:
|
||||||
"""Calcule les moyennes des étudiants dans ce module
|
"""Calcule les moyennes des étudiants dans ce module
|
||||||
@ -140,34 +140,35 @@ def compute_module_moy(
|
|||||||
ou NaN si les évaluations (dans lesquelles l'étudiant à des notes)
|
ou NaN si les évaluations (dans lesquelles l'étudiant à des notes)
|
||||||
ne donnent pas de coef vers cette UE.
|
ne donnent pas de coef vers cette UE.
|
||||||
"""
|
"""
|
||||||
nb_etuds = len(evals_notes)
|
nb_etuds, nb_evals = evals_notes_df.shape
|
||||||
nb_ues = evals_poids.shape[1]
|
nb_ues = evals_poids_df.shape[1]
|
||||||
etud_moy_module_arr = np.zeros((nb_etuds, nb_ues))
|
assert evals_poids_df.shape[0] == nb_evals # compat notes/poids
|
||||||
evals_poids_arr = evals_poids.to_numpy().transpose() * [
|
evals_coefs = np.array([e.coefficient for e in evaluations], dtype=float).reshape(
|
||||||
e.coefficient for e in evaluations
|
-1, 1
|
||||||
]
|
)
|
||||||
# -> evals_poids_arr shape : (nb_ues, nb_evals)
|
evals_poids = evals_poids_df.values * evals_coefs
|
||||||
|
# -> evals_poids_arr shape : (nb_evals, nb_ues)
|
||||||
|
assert evals_poids.shape == (nb_evals, nb_ues)
|
||||||
# Remet les notes sur 20 (sauf notes spéciales <= -1000):
|
# Remet les notes sur 20 (sauf notes spéciales <= -1000):
|
||||||
evals_notes_arr = np.where(evals_notes.values > -1000, evals_notes.values, 0.0) / [
|
evals_notes = np.where(
|
||||||
e.note_max / 20.0 for e in evaluations
|
evals_notes_df.values > -1000, evals_notes_df.values, 0.0
|
||||||
]
|
) / [e.note_max / 20.0 for e in evaluations]
|
||||||
for i in range(nb_etuds):
|
# Les poids des évals pour les étudiant: là où il a des notes non neutralisées
|
||||||
# note_vect: array [note_ue1, note_ue2, ...] de l'étudiant i
|
# Attention: les NaN (codant les absents) sont remplacés par des 0 dans
|
||||||
note_vect = evals_notes_arr[i]
|
# evals_notes_arr mais pas dans evals_poids_etuds_arr
|
||||||
# Les poids des évals pour cet étudiant: là où il a des notes non neutralisées
|
# (la comparaison est toujours false face à un NaN)
|
||||||
# Attention: les NaN (codant les absents) sont remplacés par des 0 dans
|
# shape: (nb_etuds, nb_evals, nb_ues)
|
||||||
# evals_notes_arr mais pas dans evals_poids_etud_arr
|
poids_stacked = np.stack([evals_poids] * nb_etuds)
|
||||||
# (la comparaison est toujours false face à un NaN)
|
evals_poids_etuds = np.where(
|
||||||
evals_poids_etud_arr = np.where(
|
np.stack([evals_notes_df.values] * nb_ues, axis=2) <= -1000.0, 0, poids_stacked
|
||||||
evals_notes.values[i] <= -1000, 0, evals_poids_arr
|
)
|
||||||
)
|
# Calcule la moyenne pondérée sur les notes disponibles
|
||||||
# Calcule la moyenne pondérée sur les notes disponibles
|
evals_notes_stacked = np.stack([evals_notes] * nb_ues, axis=2)
|
||||||
with np.errstate(invalid="ignore"): # ignore les 0/0 (-> NaN)
|
with np.errstate(invalid="ignore"): # ignore les 0/0 (-> NaN)
|
||||||
etud_moy_module_arr[i] = (note_vect * evals_poids_etud_arr).sum(
|
etud_moy_module = np.sum(
|
||||||
axis=1
|
evals_poids_etuds * evals_notes_stacked, axis=1
|
||||||
) / evals_poids_etud_arr.sum(axis=1)
|
) / np.sum(evals_poids_etuds, axis=1)
|
||||||
|
|
||||||
etud_moy_module_df = pd.DataFrame(
|
etud_moy_module_df = pd.DataFrame(
|
||||||
etud_moy_module_arr, index=evals_notes.index, columns=evals_poids.columns
|
etud_moy_module, index=evals_notes_df.index, columns=evals_poids_df.columns
|
||||||
)
|
)
|
||||||
return etud_moy_module_df
|
return etud_moy_module_df
|
||||||
|
@ -234,7 +234,7 @@ def test_module_moy_elem(test_client):
|
|||||||
"EVAL2": np.NaN, # et une ABS
|
"EVAL2": np.NaN, # et une ABS
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
evals_notes = pd.DataFrame(
|
evals_notes_df = pd.DataFrame(
|
||||||
data, index=["etud1", "etud2", "etud3", "etud4", "etud5"]
|
data, index=["etud1", "etud2", "etud3", "etud4", "etud5"]
|
||||||
)
|
)
|
||||||
# Poids des évaluations (1 ligne / évaluation)
|
# Poids des évaluations (1 ligne / évaluation)
|
||||||
@ -242,13 +242,13 @@ def test_module_moy_elem(test_client):
|
|||||||
{"UE1": 1, "UE2": 0, "UE3": 0},
|
{"UE1": 1, "UE2": 0, "UE3": 0},
|
||||||
{"UE1": 2, "UE2": 5, "UE3": 0},
|
{"UE1": 2, "UE2": 5, "UE3": 0},
|
||||||
]
|
]
|
||||||
evals_poids = pd.DataFrame(data, index=["EVAL1", "EVAL2"], dtype=float)
|
evals_poids_df = pd.DataFrame(data, index=["EVAL1", "EVAL2"], dtype=float)
|
||||||
evaluations = [
|
evaluations = [
|
||||||
Evaluation(note_max=20.0, coefficient=1.0),
|
Evaluation(note_max=20.0, coefficient=1.0),
|
||||||
Evaluation(note_max=20.0, coefficient=1.0),
|
Evaluation(note_max=20.0, coefficient=1.0),
|
||||||
]
|
]
|
||||||
etud_moy_module_df = moy_mod.compute_module_moy(
|
etud_moy_module_df = moy_mod.compute_module_moy(
|
||||||
evals_notes.fillna(0.0), evals_poids, evaluations
|
evals_notes_df.fillna(0.0), evals_poids_df, evaluations
|
||||||
)
|
)
|
||||||
NAN = 666.0 # pour pouvoir comparer NaN et NaN (car NaN != NaN)
|
NAN = 666.0 # pour pouvoir comparer NaN et NaN (car NaN != NaN)
|
||||||
r = etud_moy_module_df.fillna(NAN)
|
r = etud_moy_module_df.fillna(NAN)
|
||||||
|
Loading…
Reference in New Issue
Block a user