#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Fusionne les features GPT (specs.jsonl) aux données maison (maisons_avec_prix.json).""" import json, csv # 1) charger specs GPT specs = {} for line in open("data/processed/specs.jsonl", encoding="utf-8"): r = json.loads(line) if r.get("specs"): specs[r["uid"]] = r["specs"] print(f"Specs GPT chargées : {len(specs)}") # 2) charger maisons data = json.load(open("data/processed/maisons_avec_prix.json", encoding="utf-8")) # 3) JSON fusionné : record complet + gptSpecs imbriqué merged = [] n_match = 0 for d in data: uid = f"{d.get('source')}:{d.get('listingId')}" d2 = dict(d) d2["uid"] = uid s = specs.get(uid) d2["gptSpecs"] = s # None si absent if s: n_match += 1 merged.append(d2) json.dump(merged, open("data/processed/maisons_specs.json", "w", encoding="utf-8"), ensure_ascii=False) print(f"JSON fusionné -> maisons_specs.json ({len(merged)} records, " f"{n_match} avec specs)") # 4) CSV aplati pour analyse BOOL = ["turnkey","recently_renovated","garage","pool","waterfront", "finished_basement","fireplace","central_ac","new_construction", "income_property","renovated_kitchen","renovated_bathroom", "large_lot","quiet_area"] FLOOR = ["bois_franc","ceramique","plancher_flottant","tapis","vinyle","beton","autre"] HEAT = ["electrique","plinthes","thermopompe","bois","gaz","mazout","radiant","geothermie","autre"] cols = (["uid","source","listingId","price","currency","city","province", "ptype","sqft_raw","lot_raw","beds","baths","yearBuilt","parking", "has_gpt","g_condition","g_countertop","g_view"] + ["g_"+b for b in BOOL] + ["fl_"+f for f in FLOOR] + ["heat_"+h for h in HEAT] + ["g_highlights"]) with open("data/processed/maisons_specs.csv", "w", newline="", encoding="utf-8") as fh: w = csv.writer(fh) w.writerow(cols) for d in data: uid = f"{d.get('source')}:{d.get('listingId')}" p = d.get("property") or {} ad = d.get("address") or {} s = specs.get(uid) row = [uid, d.get("source"), d.get("listingId"), d.get("priceNumber"), d.get("currency"), ad.get("city"), ad.get("province"), (p.get("buildingType") or p.get("type")), p.get("squareFeet"), p.get("lotSize"), p.get("bedrooms"), p.get("bathrooms"), p.get("yearBuilt"), p.get("parkingSpaces"), 1 if s else 0, (s or {}).get("condition",""), (s or {}).get("countertop",""), (s or {}).get("view","")] row += [int(bool((s or {}).get(b))) if s else "" for b in BOOL] fl = set((s or {}).get("flooring") or []) row += [int(f in fl) if s else "" for f in FLOOR] ht = set((s or {}).get("heating") or []) row += [int(h in ht) if s else "" for h in HEAT] row += ["; ".join((s or {}).get("highlights") or [])] w.writerow(row) print(f"CSV aplati -> maisons_specs.csv ({len(cols)} colonnes)") # 5) petit récap de distribution import collections cond = collections.Counter(s.get("condition") for s in specs.values()) print("\nRépartition 'condition' :", dict(cond)) for b in ["turnkey","recently_renovated","central_ac","pool","waterfront", "renovated_kitchen","income_property"]: n = sum(1 for s in specs.values() if s.get(b)) print(f" {b:20s}: {n:5d} ({n/len(specs)*100:.1f}%)")