SPB Git
2.7 KB · 42 lines python
1"""Cas 4 — portefeuille multirésidentiel interrégional (données synthétiques) : calculs PARTAGÉS par les chapitres 36, 38, 40, 43 et 48."""2from __future__ import annotations3import pathlib4import numpy as np, pandas as pd56ROOT = pathlib.Path(__file__).resolve().parents[3]7D = ROOT / "data/synthetic"89def charger() -> dict:10    pf = pd.read_csv(D / "cas4_portefeuille.csv"); se = pd.read_csv(D / "cas4_portefeuille_series.csv")11    se["trimestre"] = pd.PeriodIndex(se["trimestre"], freq="Q")12    return {"portefeuille": pf, "series": se}1314def sommaire(pf: pd.DataFrame) -> dict:15    g = pf.groupby("rmr").agg(n=("id_immeuble", "count"), logements=("nb_logements", "sum"), valeur=("valeur_2026", "sum"), rne=("rne_2026", "sum"), dette=("dette", "sum"))16    g["taux_pondere"] = g["rne"] / g["valeur"]; g["rpv"] = g["dette"] / g["valeur"]; g["valeur_par_logement"] = g["valeur"] / g["logements"]17    tot = {"n": len(pf), "logements": int(pf["nb_logements"].sum()), "valeur": float(pf["valeur_2026"].sum()), "rne": float(pf["rne_2026"].sum()), "dette": float(pf["dette"].sum())}18    tot["taux_pondere"] = tot["rne"] / tot["valeur"]; tot["rpv"] = tot["dette"] / tot["valeur"]19    tot["part_zone_inondable"] = float(pf.loc[pf["zone_inondable"] == 1, "valeur_2026"].sum() / tot["valeur"])20    return {"par_rmr": g, "total": tot}2122def croissance_rne(se: pd.DataFrame) -> pd.DataFrame:23    """Taux de croissance annualisé du RNE par immeuble (régression de ln RNE sur le temps, 2016T1-2026T2)."""24    out = []25    for k, g in se.groupby("id_immeuble"):26        t = np.arange(len(g)) / 4.0; y = np.log(g["rne_trimestriel"].values)27        b = np.polyfit(t, y, 1)[0]28        out.append({"id_immeuble": k, "croissance_annuelle": float(np.exp(b) - 1), "volatilite": float(np.std(np.diff(y)) * 2)})29    return pd.DataFrame(out)3031def effets_regionaux(pf: pd.DataFrame) -> pd.DataFrame:32    """Régression du log du taux global sur l'état, la taille, les risques et des indicatrices de RMR (référence Montréal)."""33    from . import hedonique as h34    X = pd.DataFrame({"const": 1.0, "etat": pf["etat_1a5"] - 3, "ln_logements": np.log(pf["nb_logements"] / 12), "inondable": pf["zone_inondable"], "sol": pf["contamination_sol"], "age": (pf["age"] - 50) / 10})35    for r in ["Québec", "Gatineau", "Sherbrooke", "Trois-Rivières", "Saguenay"]:36        X[f"rmr_{r}"] = (pf["rmr"] == r).astype(float)37    res = h.mco(X.values, np.log(pf["taux_global"].values))38    return pd.DataFrame({"coef": res["beta"], "se_hc1": res["se_hc1"]}, index=X.columns).assign(effet_pct=lambda d: np.exp(d["coef"]) - 1)3940def tout() -> dict:41    d = charger(); return {**d, "sommaire": sommaire(d["portefeuille"]), "croissance": croissance_rne(d["series"]), "effets": effets_regionaux(d["portefeuille"])}42
Files · 8dfc6ca7769188d087f58c82e02a063bfba99ae6
Menu

Theme