SPB Git

spb/wp38_uqo

Public
3.4 KB · 61 lines python
1"""Phase 4 features — region × category count matrices under the three weighting schemes and the sample variants.23Outputs data/processed/rc_counts.parquet (long format): sample ∈ {S_R, S_R0, S_A}, scheme ∈ {L, M, T}, region, category, n4plus store-level table data/processed/store_panel.parquet used by every model (one row per store in S_A with region, weights, size).5"""6from __future__ import annotations7import json8import numpy as np, pandas as pd9from src.common import ROOT, P, REGIONS, get_logger, ledger, register_output, write_json1011log = get_logger("features.rc")12PROC = ROOT / "data" / "processed"131415def store_category_table():16    li = pd.read_parquet(P["interim"] / "listings_clean.parquet")17    sm = pd.read_parquet(P["interim"] / "stores_master.parquet")18    a = li[li.f_analysis_assort]19    sc = a.groupby(["store_id", "category"]).size().rename("n").reset_index()20    sc = sc.merge(sm[["id", "region_final", "region_source", "n_listings", "platform", "store_kind", "certified", "first_source", "origin_class"]], left_on="store_id", right_on="id").drop(columns="id")21    sc = sc.merge(sm[["id", "region_dbfirst", "region_db"]], left_on="store_id", right_on="id").drop(columns="id")22    return sc, sm232425def build(sc: pd.DataFrame) -> pd.DataFrame:26    rows = []27    sizes = sc.groupby("store_id").n.sum()28    cut = sizes.quantile(0.99)29    for sample, mask in (("S_R", sc.region_final != "Inconnue"), ("S_R0", sc.region_db.notna()), ("S_A", pd.Series(True, index=sc.index))):30        d = sc[mask].copy()31        if sample == "S_R0": d["region_final"] = d.region_dbfirst32        d["w_L"] = d.n.astype(float)33        d["w_M"] = d.n / d.store_id.map(sizes)34        d["w_T"] = np.where(d.store_id.map(sizes) > cut, 0.0, d.n.astype(float))35        for scheme in ("L", "M", "T"):36            g = d.groupby(["region_final", "category"])[f"w_{scheme}"].sum().reset_index()37            g.columns = ["region", "category", "n"]; g["sample"] = sample; g["scheme"] = scheme38            rows.append(g)39    out = pd.concat(rows, ignore_index=True)40    return out414243def main():44    sc, sm = store_category_table()45    rc = build(sc)46    rc.to_parquet(PROC / "rc_counts.parquet", index=False); register_output(PROC / "rc_counts.parquet", "features.rc")47    sc.to_parquet(PROC / "store_category.parquet", index=False); register_output(PROC / "store_category.parquet", "features.rc")48    sp = sm[["id", "region_final", "region_source", "region_conflict", "n_listings", "n_categories", "platform", "store_kind", "certified", "cert_adq", "cert_lpq",49             "first_source", "origin_class", "median_price", "main_category", "lat", "lng"]].copy()50    sp = sp[sp.n_listings > 0]51    sp.to_parquet(PROC / "store_panel.parquet", index=False); register_output(PROC / "store_panel.parquet", "features.rc")52    summ = {"stores_S_A": int(sp.shape[0]), "stores_S_R": int((sp.region_final != "Inconnue").sum()), "stores_S_R0": int(sm.region_db.notna().sum()),53            "listings_S_R": int(rc.query("sample=='S_R' and scheme=='L'").n.sum()), "listings_S_A": int(rc.query("sample=='S_A' and scheme=='L'").n.sum()),54            "top1pct_cut": float(sc.groupby('store_id').n.sum().quantile(0.99)),55            "stores_by_region_S_R": sp[sp.region_final != "Inconnue"].region_final.value_counts().to_dict()}56    write_json(summ, ROOT / "experiments" / "features_rc.json", "features.rc"); ledger("features.region_category", **summ); log.info(json.dumps(summ, ensure_ascii=False))575859if __name__ == "__main__":60    main()61
Files · 1a9fe871a9dfb962987357dba4d30489254507e2
Menu

Theme