File size: 3,966 Bytes
ba7b0bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# unihvac/tables.py
from __future__ import annotations
import pandas as pd
import numpy as np

def print_monthly_tables_split(df: pd.DataFrame, location: str, time_step_hours: float):
    """
    Table 1: Monthly HVAC electricity + temps
    Table 2: Monthly occupancy
    """
    drop_cols = [c for c in df.columns if c.startswith("has_") or c == "feature_registry"]
    df_clean = df.drop(columns=drop_cols, errors="ignore").copy()

    if "month" not in df_clean.columns:
        return

    df_clean["month"] = df_clean["month"].round().astype(int)

    # 1. Electricity / Energy Calculation
    energy_cols = []
    peak_cols = []
    if "elec_power" in df_clean.columns:
        if "elec_power_kw" not in df_clean.columns:
            df_clean["elec_power_kw"] = df_clean["elec_power"] / 1000.0
        if "elec_energy_kwh" not in df_clean.columns:
            df_clean["elec_energy_kwh"] = df_clean["elec_power_kw"] * time_step_hours
        energy_cols.append("elec_energy_kwh")
        peak_cols.append("elec_power_kw")

    # 2. Temperature Aggregation
    temp_cols = [c for c in ["outdoor_temp", "core_temp", "perim1_temp", "perim2_temp", "perim3_temp", "perim4_temp"] 
                 if c in df_clean.columns]
    
    agg1 = {c: "sum" for c in energy_cols}
    agg1.update({c: "max" for c in peak_cols})
    agg1.update({c: "mean" for c in temp_cols})
    tbl1 = df_clean.groupby("month").agg(agg1).sort_index()

    # 3. Occupancy Aggregation
    occ_cols = [c for c in df_clean.columns if c.endswith("_occ_count")]
    tbl2 = df_clean.groupby("month")[occ_cols].mean().sort_index() if occ_cols else pd.DataFrame()
    if not tbl2.empty:
        tbl2["occ_mean_total"] = tbl2.sum(axis=1)

    print("\n" + "=" * 110)
    print(f"MONTHLY ELECTRICITY + TEMPERATURE — {location}")
    print("=" * 110)
    print(tbl1.round(2).to_string())
    print("\n" + "=" * 110)
    print(f"MONTHLY OCCUPANCY — {location}")
    print("=" * 110)
    print(tbl2.round(3).to_string())
    print("=" * 110 + "\n")


def print_monthly_tables_extra(df: pd.DataFrame, location: str) -> None:
 
    d = df.copy()
    if "month" not in d.columns:
        return
    d["month"] = d["month"].round().astype(int)

    violation_cols = [c for c in ["comfort_violation_degCh", "comfort_violation_fixed_degCh"] if c in d.columns]
    tbl_sums = d.groupby("month")[violation_cols].sum()


    occ_cols = [c for c in d.columns if c.endswith("_occ_count")]
    total_occ = d[occ_cols].sum(axis=1)
    is_occupied = total_occ > 1e-6
    d_occ = d[is_occupied].copy()


    def person_weighted_ppd(group):
        occ = group[occ_cols].sum(axis=1)
        raw_ppd = group["ppd_weighted"]
        return (raw_ppd * occ).sum() / occ.sum() if occ.sum() > 0 else np.nan

    if not d_occ.empty and "ppd_weighted" in d_occ.columns:
        ppd_monthly = d_occ.groupby("month", group_keys=False).apply(person_weighted_ppd)
        ppd_monthly = ppd_monthly.clip(lower=5.0)
        
        pmv_monthly = d_occ.groupby("month")["pmv_weighted"].mean()
        rh_monthly = d_occ.groupby("month")["rh_weighted"].mean()

        tbl_means = pd.DataFrame({
            "ppd_weighted": ppd_monthly,
            "pmv_weighted": pmv_monthly,
            "rh_weighted_%": rh_monthly
        })
        tbl3a = pd.concat([tbl_sums, tbl_means], axis=1).sort_index()
    else:
        tbl3a = tbl_sums


    outdoor_vars = [c for c in ["outdoor_temp", "outdoor_dewpoint", "outdoor_wetbulb"] if c in d.columns]
    tbl3b = d.groupby("month")[outdoor_vars].mean().sort_index() if outdoor_vars else None


    print("\n" + "=" * 110)
    print(f"MONTHLY COMFORT OUTCOMES (Occupancy Weighted) — {location}")
    print("=" * 110)
    print(tbl3a.round(3).to_string())
    print("=" * 110)


    if tbl3b is not None:
        print("\n" + "=" * 110)
        print(f"MONTHLY OUTDOOR CONDITIONS — {location}")
        print("=" * 110)
        print(tbl3b.round(3).to_string())
        print("=" * 110)