"""MP1 · paso 41: muestra del cotejo de 30 casos (pre-registro §11), semilla «mp1-cotejo-30». Imagen bquantagents-worker. Escribe /w/interno/cotejo/muestra.csv (casos con los valores de nuestros datos) y /w/interno/cotejo/objetivos.json (para el paso 40). Desviación declarada: los 4 casos de (e) se sortean entre las series de la PLACSP (su ficha original es el ATOM). """ import json, hashlib, os import numpy as np, pandas as pd SEED = int(hashlib.md5(b"mp1-cotejo-30").hexdigest()[:8], 16) rng = np.random.default_rng(SEED) OUT = "/w/interno/cotejo"; os.makedirs(OUT, exist_ok=True) L = pd.read_csv("/w/interno/lotes.csv", dtype={"licitacion_id": "string", "lote_u": "string", "organo_clave": "string", "cpv_div": "string", "cpv_cel": "string"}, low_memory=False) def toma(df, k): return df.iloc[rng.choice(len(df), size=min(k, len(df)), replace=False)] if len(df) else df filas = [] pd_des = pd.read_csv("/w/interno/mp1_des/predicciones.csv", dtype={"licitacion_id": "string", "lote_u": "string"}) t = pd_des[pd_des["ventana"] == "test"] for k, sub in ((3, t[t["y"] == 1]), (9, t[t["y"] == 0])): for _, r in toma(sub, k).iterrows(): filas.append({"grupo": "ab", "licitacion_id": r["licitacion_id"], "lote_u": r["lote_u"], "y_des": int(r["y"]), "anio_zip": 2026}) pm = pd.read_csv("/w/interno/mp1_mod/predicciones.csv", dtype={"licitacion_id": "string", "lote_u": "string"}) t = pm[pm["ventana"] == "test"] for k, sub in ((4, t[t["y"] == 1]), (4, t[t["y"] == 0])): for _, r in toma(sub, k).iterrows(): filas.append({"grupo": "c", "licitacion_id": r["licitacion_id"], "lote_u": r["lote_u"], "y_mod": int(r["y"]), "anio_zip": 2025}) m = pd.DataFrame(filas).merge(L, on=["licitacion_id", "lote_u"], how="left") if os.path.exists("/w/interno/mp1_rec/predicciones.csv"): pr = pd.read_csv("/w/interno/mp1_rec/predicciones.csv", dtype={"licitacion_id": "string"}) sel = pd.concat([toma(pr[pr["y"] == 1], 3), toma(pr[pr["y"] == 0], 3)]) rec = pd.read_csv("/w/interno/recurso.csv", dtype={"licitacion_id": "string"}) sel = sel[["licitacion_id", "y"]].rename(columns={"y": "y_rec"}).merge(rec, on="licitacion_id", how="left", suffixes=("", "_r")) sel["grupo"] = "d"; sel["anio_zip"] = 2026 m = pd.concat([m, sel], ignore_index=True) if os.path.exists("/w/interno/mp1_ser/predicciones.csv"): ps = pd.read_csv("/w/interno/mp1_ser/predicciones.csv", dtype={"licitacion_id": "string"}) t = ps[(ps["ventana"] == "test") & (ps["fuente"] == "PLACSP")] sel = pd.concat([toma(t[t["y"] == 1], 2), toma(t[t["y"] == 0], 2)]) sel = sel.rename(columns={"licitacion_id": "serie", "y": "y_ser"})[["serie", "organo_clave", "y_ser", "t", "clase", "cpv_div"]] sel["grupo"] = "e" m = pd.concat([m, sel], ignore_index=True) m["clave"] = [f"c{i:02d}" for i in range(len(m))] m.to_csv(f"{OUT}/muestra.csv", index=False) obj = [] for _, r in m.iterrows(): if r["grupo"] in ("ab", "c", "d") and isinstance(r["licitacion_id"], str): idn = r["licitacion_id"].split(":", 1)[1] carpeta = "licitaciones" if "licitacionesPerfilContratante" in idn else "agregacion" base = {"licitaciones": "licitacionesPerfilesContratanteCompleto3", "agregacion": "PlataformasAgregadasSinMenores"}[carpeta] anio = int(r["anio_zip"]) zips = [f"{carpeta}/{base}_{a}.zip" for a in range(anio, 2027)] obj.append({"clave": r["clave"], "zip": zips, "id": idn}) json.dump(obj, open(f"{OUT}/objetivos.json", "w"), indent=1) print(m["grupo"].value_counts().to_dict(), len(obj))