TeX 55.1%
Python 44.2%
1#!/usr/bin/env python32# Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca3"""Phase 4 — NaN-safe Monte Carlo summary from results/simulation/metrics.parquet → summary.csv (means + Monte Carlo s.e.).4Cells for which a method is not estimable (NaN) are excluded from that method's averages; `share_est` reports their share."""5from __future__ import annotations67import sys8from pathlib import Path910sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))11import polars as pl1213from sharp_hpi import config as C1415OUT = C.RESULTS / "simulation"16m = pl.read_parquet(OUT / "metrics.parquet")17cols = ["rmse_ret", "mae_ret", "bias_ret", "rmse_lvl", "cov95", "cov95_ret", "corr_ret", "lag_xcorr", "revision_rmse", "share_est", "secs"]18m = m.with_columns([pl.col(c).fill_nan(None) for c in cols])19# per replication first (so the Monte Carlo s.e. is over replications, not cells)20rep = m.group_by(["scenario", "method", "level", "rep"]).agg([pl.col(c).mean().alias(c) for c in cols] + [pl.len().alias("cells")])21summ = rep.group_by(["scenario", "method", "level"]).agg(22 pl.col("cells").mean().alias("cells"), pl.col("rep").n_unique().alias("reps"),23 *[pl.col(c).mean().alias(c) for c in cols],24 *[(pl.col(c).std() / pl.col(c).count().sqrt()).alias(c + "_mcse") for c in ["rmse_ret", "bias_ret", "rmse_lvl", "cov95"]],25).sort(["scenario", "level", "rmse_ret"])26summ.write_csv(OUT / "summary.csv")27pl.Config.set_tbl_rows(200); pl.Config.set_tbl_width_chars(220)28print(summ.filter(pl.col("level") == "municipality").select(["scenario", "method", "reps", "rmse_ret", "rmse_ret_mcse", "bias_ret", "cov95", "lag_xcorr", "share_est"]))29