This commit is contained in:
Jun-te Kim 2026-01-27 18:52:51 +00:00
parent 0254c945e8
commit 1acf4f4d6a
6 changed files with 340 additions and 328 deletions

View file

@ -19,3 +19,4 @@ ipykernel>=6.25,<7
pydantic-settings<2 pydantic-settings<2
pyyaml>=6.0.1 pyyaml>=6.0.1
pydantic>=1.10.7,<2 pydantic>=1.10.7,<2
sqlmodel

View file

@ -1,7 +1,7 @@
from sqlalchemy import create_engine from sqlalchemy import create_engine
from contextlib import contextmanager from contextlib import contextmanager
from backend.app.config import get_settings from backend.app.config import get_settings
from sqlmodel import Session # from sqlmodel import Session
connection_string = "postgresql+{drivername}://{username}:{password}@{server}:{port}/{dbname}" connection_string = "postgresql+{drivername}://{username}:{password}@{server}:{port}/{dbname}"
db_string = connection_string.format( db_string = connection_string.format(

View file

@ -11,3 +11,4 @@ boto3==1.35.44
openpyxl==3.1.2 openpyxl==3.1.2
# Basic # Basic
pytz pytz
sqlmodel

View file

@ -98,8 +98,17 @@ def main():
results.append(tmp) results.append(tmp)
final_df = pd.concat(results, ignore_index=True) final_df = pd.concat(results, ignore_index=True)
a = final_df[["best_match_lexiscore","Address 1", "best_match_address", "Postcode", "UPRN", "best_match_uprn"]] # add levi score to viewing a = final_df[[
"best_match_lexiscore","Address 1",
"best_match_address", "Postcode",
"UPRN", "best_match_uprn"
]] # add levi score to viewing
b = final_df[final_df["best_match_lexiscore"]>0] # add levi score to viewing b = final_df[final_df["best_match_lexiscore"]>0] # add levi score to viewing
b = b[[
"best_match_lexiscore","Address 1",
"best_match_address", "Postcode",
"UPRN", "best_match_uprn"
]]
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View file

@ -1,111 +1,111 @@
import pandas as pd import pandas as pd
epc_c_recommendations = pd.read_excel( # epc_c_recommendations = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no " # "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no "
"solid floor, ashp 3.0 - corrected.xlsx" # "solid floor, ashp 3.0 - corrected.xlsx"
) # )
epc_b_recommendations = pd.read_excel( # epc_b_recommendations = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC B - no " # "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC B - no "
"solid floor, ashp 3.0 - corrected.xlsx" # "solid floor, ashp 3.0 - corrected.xlsx"
) # )
epc_c_movers = epc_b_recommendations[ # epc_c_movers = epc_b_recommendations[
epc_b_recommendations["current_epc_rating"] == "Epc.C" # epc_b_recommendations["current_epc_rating"] == "Epc.C"
] # ]
epc_c_movers["property_type"].value_counts() # epc_c_movers["property_type"].value_counts()
house_epc_c_movers = epc_c_movers[ # house_epc_c_movers = epc_c_movers[
epc_c_movers["property_type"] == "House" # epc_c_movers["property_type"] == "House"
] # ]
house_epc_c_movers_with_solar = house_epc_c_movers[ # house_epc_c_movers_with_solar = house_epc_c_movers[
~pd.isnull(house_epc_c_movers["solar_pv"]) | ~pd.isnull(house_epc_c_movers["solar_pv_with_battery"]) # ~pd.isnull(house_epc_c_movers["solar_pv"]) | ~pd.isnull(house_epc_c_movers["solar_pv_with_battery"])
] # ]
house_epc_c_movers_with_a_heatpump = house_epc_c_movers[ # house_epc_c_movers_with_a_heatpump = house_epc_c_movers[
~pd.isnull(house_epc_c_movers["air_source_heat_pump"]) # ~pd.isnull(house_epc_c_movers["air_source_heat_pump"])
] # ]
flat_epc_c_movers = epc_c_movers[ # flat_epc_c_movers = epc_c_movers[
epc_c_movers["property_type"] == "Flat" # epc_c_movers["property_type"] == "Flat"
] # ]
epc_c_recommendations["sap_points"].mean() # epc_c_recommendations["sap_points"].mean()
epc_c_recommendations["sap_points"].mean() # epc_c_recommendations["sap_points"].mean()
measure_cols = [ # measure_cols = [
"air_source_heat_pump", # "air_source_heat_pump",
"boiler_upgrade", # "boiler_upgrade",
"cavity_wall_insulation", # "cavity_wall_insulation",
"double_glazing", # "double_glazing",
"external_wall_insulation", # "external_wall_insulation",
"flat_roof_insulation", # "flat_roof_insulation",
"high_heat_retention_storage_heaters", # "high_heat_retention_storage_heaters",
"internal_wall_insulation", # "internal_wall_insulation",
"loft_insulation", # "loft_insulation",
"low_energy_lighting", # "low_energy_lighting",
"mechanical_ventilation", # "mechanical_ventilation",
"room_roof_insulation", # "room_roof_insulation",
"roomstat_programmer_trvs", # "roomstat_programmer_trvs",
"sealing_open_fireplace", # "sealing_open_fireplace",
"secondary_glazing", # "secondary_glazing",
"secondary_heating", # "secondary_heating",
"solar_pv", # "solar_pv",
"solar_pv_with_battery", # "solar_pv_with_battery",
"suspended_floor_insulation", # "suspended_floor_insulation",
"time_temperature_zone_control", # "time_temperature_zone_control",
] # ]
epc_c_melted = ( # epc_c_melted = (
epc_c_recommendations # epc_c_recommendations
.melt( # .melt(
id_vars=[c for c in epc_c_recommendations.columns if c not in measure_cols], # id_vars=[c for c in epc_c_recommendations.columns if c not in measure_cols],
value_vars=measure_cols, # value_vars=measure_cols,
var_name="measure_type", # var_name="measure_type",
value_name="value", # value_name="value",
) # )
.dropna(subset=["value"]) # .dropna(subset=["value"])
) # )
epc_c_melted = epc_c_melted[epc_c_melted["value"] > 0] # epc_c_melted = epc_c_melted[epc_c_melted["value"] > 0]
epc_c_measures = epc_c_melted["measure_type"].value_counts(normalize=True).to_frame().reset_index() # epc_c_measures = epc_c_melted["measure_type"].value_counts(normalize=True).to_frame().reset_index()
epc_b_melted = ( # epc_b_melted = (
epc_b_recommendations # epc_b_recommendations
.melt( # .melt(
id_vars=[c for c in epc_b_recommendations.columns if c not in measure_cols], # id_vars=[c for c in epc_b_recommendations.columns if c not in measure_cols],
value_vars=measure_cols, # value_vars=measure_cols,
var_name="measure_type", # var_name="measure_type",
value_name="value", # value_name="value",
) # )
.dropna(subset=["value"]) # .dropna(subset=["value"])
) # )
epc_b_melted = epc_b_melted[epc_b_melted["value"] > 0] # epc_b_melted = epc_b_melted[epc_b_melted["value"] > 0]
epc_b_measures = epc_b_melted["measure_type"].value_counts(normalize=True).to_frame().reset_index() # epc_b_measures = epc_b_melted["measure_type"].value_counts(normalize=True).to_frame().reset_index()
measures_compared = epc_c_measures.merge( # measures_compared = epc_c_measures.merge(
epc_b_measures, # epc_b_measures,
left_on="measure_type", # left_on="measure_type",
right_on="measure_type", # right_on="measure_type",
suffixes=("_epc_c", "_epc_b"), # suffixes=("_epc_c", "_epc_b"),
) # )
epc_c_retrofits = epc_c_recommendations[ # epc_c_retrofits = epc_c_recommendations[
epc_c_recommendations["total_retrofit_cost"] > 0 # epc_c_recommendations["total_retrofit_cost"] > 0
] # ]
epc_b_retrofits = epc_b_recommendations[ # epc_b_retrofits = epc_b_recommendations[
epc_b_recommendations["total_retrofit_cost"] > 0 # epc_b_recommendations["total_retrofit_cost"] > 0
] # ]
epc_c_retrofits["sap_points"].mean() # epc_c_retrofits["sap_points"].mean()
epc_b_retrofits["sap_points"].mean() # epc_b_retrofits["sap_points"].mean()
properties_in_both = epc_c_retrofits.merge(epc_b_retrofits, on="uprn", suffixes=("_epc_c", "_epc_b")) # properties_in_both = epc_c_retrofits.merge(epc_b_retrofits, on="uprn", suffixes=("_epc_c", "_epc_b"))
properties_in_both["total_retrofit_cost_epc_c"].mean() # properties_in_both["total_retrofit_cost_epc_c"].mean()
properties_in_both["sap_points_epc_c"].mean() # properties_in_both["sap_points_epc_c"].mean()
properties_in_both["total_retrofit_cost_epc_b"].mean() # properties_in_both["total_retrofit_cost_epc_b"].mean()
properties_in_both["sap_points_epc_b"].mean() # properties_in_both["sap_points_epc_b"].mean()
# Solar PV savings - we need the amount of solar PV bill savings # Solar PV savings - we need the amount of solar PV bill savings
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
@ -114,14 +114,12 @@ from backend.app.db.models.recommendations import Recommendation, Plan, PlanReco
from backend.app.db.models.portfolio import PropertyModel, PropertyDetailsEpcModel from backend.app.db.models.portfolio import PropertyModel, PropertyDetailsEpcModel
from collections import defaultdict from collections import defaultdict
PORTFOLIO_ID = 434 # Peabody PORTFOLIO_ID = 485 # Peabody
SCENARIOS = [ SCENARIOS = [
904, 970
905
] ]
scenario_names = { scenario_names = {
904: "EPC C - no solid floor, ashp 3.0", 970: "EPC C - no solid floor, ashp 3.0",
905: "EPC B - no solid floor, ashp 3.0",
} }
@ -233,259 +231,266 @@ properties_data, plans_data, recommendations_data = get_data(
recommendations_df = pd.DataFrame(recommendations_data) recommendations_df = pd.DataFrame(recommendations_data)
properties_df = pd.DataFrame(properties_data) properties_df = pd.DataFrame(properties_data)
solar_pv_recommendations = recommendations_df[recommendations_df["measure_type"] == "solar_pv"] with pd.ExcelWriter("hackney.xlsx", engine="openpyxl") as writer:
average_savings = solar_pv_recommendations.groupby("scenario_id")["energy_cost_savings"].mean().reset_index() recommendations_df.to_excel(writer, sheet_name="recommendations", index=False)
properties_df.to_excel(writer, sheet_name="properties", index=False)
# Check tenures
initial_asset_data = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/2025_11_11 - Peabody "
"- Data Extracts for Domna.xlsx",
sheet_name="Properties"
)
sustainability_data = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/2025_11_11 - Peabody "
"- Data Extracts for Domna.xlsx",
sheet_name="Sustainability"
)
sustainability_sample = sustainability_data[ # solar_pv_recommendations = recommendations_df[recommendations_df["measure_type"] == "solar_pv"]
sustainability_data["UPRN"].isin(properties_df["uprn"].astype(int).astype(str).values) # average_savings = solar_pv_recommendations.groupby("scenario_id")["energy_cost_savings"].mean().reset_index()
]
sustainability_sample = sustainability_sample.merge(
initial_asset_data, left_on="Org Ref", right_on="UPRN", suffixes=("_sustainability", "_initial_asset")
)
block_sizes = initial_asset_data["BlockCode"].value_counts().reset_index().sort_values("count", ascending=False)
block_sizes.to_excel("/Users/khalimconn-kowlessar/Downloads/peabody_block_sizes.xlsx", index=False)
initial_asset_data.columns # # Check tenures
initial_asset_data["LeaseType"].value_counts() # initial_asset_data = pd.read_excel(
# "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/2025_11_11 - Peabody "
# "- Data Extracts for Domna.xlsx",
# sheet_name="Properties"
# )
# sustainability_data = pd.read_excel(
# "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/2025_11_11 - Peabody "
# "- Data Extracts for Domna.xlsx",
# sheet_name="Sustainability"
# )
# sustainability_sample["Tenure Group"].value_counts() # sustainability_sample = sustainability_data[
# Tenure Group # sustainability_data["UPRN"].isin(properties_df["uprn"].astype(int).astype(str).values)
# General Needs 57787 # ]
# Home Ownership 25471
# Care & Supported Housing 4239
# Rental 2677
# Other 188
df = sustainability_sample["Ownership Type"].value_counts().to_frame().reset_index() # sustainability_sample = sustainability_sample.merge(
df.to_excel("/Users/khalimconn-kowlessar/Downloads/sustainability_tenures.xlsx", index=False) # initial_asset_data, left_on="Org Ref", right_on="UPRN", suffixes=("_sustainability", "_initial_asset")
# )
tenure_groups = sustainability_sample["Tenure Group"].value_counts().to_frame().reset_index() # block_sizes = initial_asset_data["BlockCode"].value_counts().reset_index().sort_values("count", ascending=False)
tenure_groups.to_excel("/Users/khalimconn-kowlessar/Downloads/sustainability_tenure_groups.xlsx", index=False) # block_sizes.to_excel("/Users/khalimconn-kowlessar/Downloads/peabody_block_sizes.xlsx", index=False)
initial_asset_data[~pd.isnull(initial_asset_data["BlockCode"])]["Tenure Group"].value_counts() # initial_asset_data.columns
# initial_asset_data["LeaseType"].value_counts()
sample_data = initial_asset_data[ # # sustainability_sample["Tenure Group"].value_counts()
~initial_asset_data["Ownership Type"].isin( # # Tenure Group
[ # # General Needs 57787
# Commercial # Everything is resi - based on the Residential Indicator variable - all are true # # Home Ownership 25471
# Freeholder # # Care & Supported Housing 4239
"FREEHOLDER", # 19517 properties # # Rental 2677
# HOMEBUY / EQUITY LOAN # # Other 188
"Rent to Homebuy", # 1 property
# Leaseholder
"LEASEHOLD 100%", # 8455 properties
"Owned and Managed - 999 year lease", # 2076 properties
"Managed but not Owned-Private Lease", # 159 properties
"Owned and managed LEASEHOLD", # 26 properties
# Outright Sale - can't find anything matching
# SHARED EQUITY
"Shared Ownership", # 4065 properties
"Shared Ownership Owned Not Managed", # 23 properties
# Extra categories which seem sensible to exclude
"NOT MANAGED AND NOT OWNED"
]
)
]
sample_data["Ownership Type"].value_counts() # df = sustainability_sample["Ownership Type"].value_counts().to_frame().reset_index()
# df.to_excel("/Users/khalimconn-kowlessar/Downloads/sustainability_tenures.xlsx", index=False)
sample_data = initial_asset_data[ # tenure_groups = sustainability_sample["Tenure Group"].value_counts().to_frame().reset_index()
initial_asset_data["Ownership Type"].isin( # tenure_groups.to_excel("/Users/khalimconn-kowlessar/Downloads/sustainability_tenure_groups.xlsx", index=False)
[
"Owned and Managed",
"Owned and Managed - 999 year lease",
"Owned and managed LEASEHOLD",
"LEASEHOLD 100%",
"DATALOAD DEFAULT"
]
)
]
dropped = initial_asset_data[~initial_asset_data["UPRN"].isin(sample_data["UPRN"].values)]
dropped["Ownership Type"].value_counts()
for value in [ # initial_asset_data[~pd.isnull(initial_asset_data["BlockCode"])]["Tenure Group"].value_counts()
# Commercial # Everything is resi, so should be fine. No matches
# Freeholder
"FREEHOLDER", # 19517 properties
# HOMEBUY / EQUITY LOAN
"Rent to Homebuy", # 1 property
# Leaseholder
"LEASEHOLD 100%", # 8455 properties
"Owned and Managed - 999 year lease", # 2076 properties
"Managed but not Owned-Private Lease", # 159 properties
"Owned and managed LEASEHOLD", # 26 properties
# Outright Sale - can't find anything matching
# SHARED EQUITY
"Shared Ownership", # 4065 properties
"Shared Ownership Owned Not Managed", # 23 properties
]:
print(initial_asset_data[initial_asset_data["Ownership Type"] == value].shape[0])
house_types = [ # sample_data = initial_asset_data[
"HOUSE", # ~initial_asset_data["Ownership Type"].isin(
"BUNGALOW", # [
"MAISONETTE", # # Commercial # Everything is resi - based on the Residential Indicator variable - all are true
"DUPLEX", # # Freeholder
] # "FREEHOLDER", # 19517 properties
# # HOMEBUY / EQUITY LOAN
# "Rent to Homebuy", # 1 property
# # Leaseholder
# "LEASEHOLD 100%", # 8455 properties
# "Owned and Managed - 999 year lease", # 2076 properties
# "Managed but not Owned-Private Lease", # 159 properties
# "Owned and managed LEASEHOLD", # 26 properties
# # Outright Sale - can't find anything matching
# # SHARED EQUITY
# "Shared Ownership", # 4065 properties
# "Shared Ownership Owned Not Managed", # 23 properties
# # Extra categories which seem sensible to exclude
# "NOT MANAGED AND NOT OWNED"
# ]
# )
# ]
guaranteed_control = [ # sample_data["Ownership Type"].value_counts()
"Owned and Managed",
"Owned and Managed - 999 year lease",
"Owned and managed LEASEHOLD",
"LEASEHOLD 100%",
"DATALOAD DEFAULT",
]
sample_data = initial_asset_data[ # sample_data = initial_asset_data[
( # initial_asset_data["Ownership Type"].isin(
initial_asset_data["Ownership Type"].isin(guaranteed_control) # [
) # "Owned and Managed",
| # "Owned and Managed - 999 year lease",
( # "Owned and managed LEASEHOLD",
(initial_asset_data["Ownership Type"] == "FREEHOLDER") # "LEASEHOLD 100%",
& # "DATALOAD DEFAULT"
(initial_asset_data["Property Type"].isin(house_types)) # ]
) # )
] # ]
# dropped = initial_asset_data[~initial_asset_data["UPRN"].isin(sample_data["UPRN"].values)]
# dropped["Ownership Type"].value_counts()
fabric_retrofit_sample = initial_asset_data[ # for value in [
initial_asset_data["Ownership Type"].isin( # # Commercial # Everything is resi, so should be fine. No matches
[ # # Freeholder
"Owned and Managed", # "FREEHOLDER", # 19517 properties
"FREEHOLDER", # # HOMEBUY / EQUITY LOAN
"DATALOAD DEFAULT", # "Rent to Homebuy", # 1 property
] # # Leaseholder
) # "LEASEHOLD 100%", # 8455 properties
] # "Owned and Managed - 999 year lease", # 2076 properties
# "Managed but not Owned-Private Lease", # 159 properties
# "Owned and managed LEASEHOLD", # 26 properties
# # Outright Sale - can't find anything matching
# # SHARED EQUITY
# "Shared Ownership", # 4065 properties
# "Shared Ownership Owned Not Managed", # 23 properties
# ]:
# print(initial_asset_data[initial_asset_data["Ownership Type"] == value].shape[0])
initial_asset_data[pd.isnull(initial_asset_data["BlockCode"])]["Ownership Type"].value_counts() # house_types = [
initial_asset_data[~pd.isnull(initial_asset_data["BlockCode"])]["Ownership Type"].value_counts() # "HOUSE",
# "BUNGALOW",
# "MAISONETTE",
# "DUPLEX",
# ]
initial_asset_data[~pd.isnull(initial_asset_data["BlockCode"])]["Property Type"].value_counts() # guaranteed_control = [
z = initial_asset_data[ # "Owned and Managed",
~pd.isnull(initial_asset_data["BlockCode"]) & initial_asset_data["Property Type"].isin(house_types) # "Owned and Managed - 999 year lease",
] # "Owned and managed LEASEHOLD",
# "LEASEHOLD 100%",
# "DATALOAD DEFAULT",
# ]
block_code_agg = z["BlockCode"].value_counts().reset_index().sort_values("count", ascending=False) # sample_data = initial_asset_data[
zz = initial_asset_data[initial_asset_data["BlockCode"] == "CHAT3343FM"] # (
# initial_asset_data["Ownership Type"].isin(guaranteed_control)
# )
# |
# (
# (initial_asset_data["Ownership Type"] == "FREEHOLDER")
# &
# (initial_asset_data["Property Type"].isin(house_types))
# )
# ]
potential_sample = initial_asset_data[ # fabric_retrofit_sample = initial_asset_data[
~pd.isnull(initial_asset_data["BlockCode"]) # initial_asset_data["Ownership Type"].isin(
] # [
# "Owned and Managed",
# "FREEHOLDER",
# "DATALOAD DEFAULT",
# ]
# )
# ]
compare = potential_sample["Property Type"].value_counts(normalize=True).to_frame().reset_index().merge( # initial_asset_data[pd.isnull(initial_asset_data["BlockCode"])]["Ownership Type"].value_counts()
initial_asset_data["Property Type"].value_counts(normalize=True).to_frame().reset_index(), # initial_asset_data[~pd.isnull(initial_asset_data["BlockCode"])]["Ownership Type"].value_counts()
left_on="Property Type",
right_on="Property Type",
suffixes=("_on_block_codes", "_overall")
)
# Comparison of smaller sample vs overall # initial_asset_data[~pd.isnull(initial_asset_data["BlockCode"])]["Property Type"].value_counts()
new_asset_data = pd.read_excel( # z = initial_asset_data[
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/2025_11_11 " # ~pd.isnull(initial_asset_data["BlockCode"]) & initial_asset_data["Property Type"].isin(house_types)
"- Peabody " # ]
"- Data Extracts for Domna v2.xlsx",
sheet_name="Properties"
)
new_sustainability_data = pd.read_excel( # block_code_agg = z["BlockCode"].value_counts().reset_index().sort_values("count", ascending=False)
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/2025_11_11 " # zz = initial_asset_data[initial_asset_data["BlockCode"] == "CHAT3343FM"]
"- Peabody "
"- Data Extracts for Domna v2.xlsx",
sheet_name="Sustainability"
)
sap_bands = pd.read_excel( # potential_sample = initial_asset_data[
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/Parity Data " # ~pd.isnull(initial_asset_data["BlockCode"])
"08012026.xlsx", # ]
)
combined = new_asset_data.merge( # compare = potential_sample["Property Type"].value_counts(normalize=True).to_frame().reset_index().merge(
new_sustainability_data, # initial_asset_data["Property Type"].value_counts(normalize=True).to_frame().reset_index(),
left_on="UPRN", # left_on="Property Type",
right_on="Org Ref", # right_on="Property Type",
suffixes=("_asset", "_sustainability") # suffixes=("_on_block_codes", "_overall")
).merge( # )
sap_bands[["OrgRef", "SAP Band", "Lodged EPC Band"]], how="left", left_on="Org Ref", right_on="OrgRef"
)
reduced_sample = combined[
~combined["AH Tenure"].isin(
["Commercial",
"Freeholder",
"HOMEBUY / EQUITY LOAN",
"Leaseholder",
"Outright Sale",
"SHARED EQUITY",
"Shared Ownership"]
)
].copy()
# property types # # Comparison of smaller sample vs overall
property_type_comparison = reduced_sample["Property Type"].value_counts(normalize=True).to_frame().reset_index().merge( # new_asset_data = pd.read_excel(
combined["Property Type"].value_counts(normalize=True).to_frame().reset_index(), # "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/2025_11_11 "
left_on="Property Type", # "- Peabody "
right_on="Property Type", # "- Data Extracts for Domna v2.xlsx",
suffixes=("_reduced_sample", "_overall") # sheet_name="Properties"
) # )
# lodged ratings # new_sustainability_data = pd.read_excel(
lodged_epc_band_comparison = reduced_sample["Lodged EPC Band"].value_counts( # "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/2025_11_11 "
normalize=True).to_frame().reset_index().merge( # "- Peabody "
combined["Lodged EPC Band"].value_counts(normalize=True).to_frame().reset_index(), # "- Data Extracts for Domna v2.xlsx",
left_on="Lodged EPC Band", # sheet_name="Sustainability"
right_on="Lodged EPC Band", # )
suffixes=("_reduced_sample", "_overall")
)
# modelled ratings # sap_bands = pd.read_excel(
modelled_epc_band_comparison = reduced_sample["SAP Band"].value_counts( # "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/Parity Data "
normalize=True).to_frame().reset_index().merge( # "08012026.xlsx",
combined["SAP Band"].value_counts(normalize=True).to_frame().reset_index(), # )
left_on="SAP Band",
right_on="SAP Band",
suffixes=("_reduced_sample", "_overall")
)
# Testing measures # combined = new_asset_data.merge(
m1 = pd.read_excel( # new_sustainability_data,
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no " # left_on="UPRN",
"solid floor, ashp 3.0 - 20250113 final.xlsx" # right_on="Org Ref",
) # suffixes=("_asset", "_sustainability")
m2 = pd.read_excel( # ).merge(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no " # sap_bands[["OrgRef", "SAP Band", "Lodged EPC Band"]], how="left", left_on="Org Ref", right_on="OrgRef"
"solid floor, no EWI or IWI, ashp 3.0 - 20250113 final.xlsx" # )
) # reduced_sample = combined[
# ~combined["AH Tenure"].isin(
# ["Commercial",
# "Freeholder",
# "HOMEBUY / EQUITY LOAN",
# "Leaseholder",
# "Outright Sale",
# "SHARED EQUITY",
# "Shared Ownership"]
# )
# ].copy()
compare = m1.merge( # # property types
m2, # property_type_comparison = reduced_sample["Property Type"].value_counts(normalize=True).to_frame().reset_index().merge(
left_on="uprn", # combined["Property Type"].value_counts(normalize=True).to_frame().reset_index(),
right_on="uprn", # left_on="Property Type",
suffixes=("_ewi_iwi", "_no_ewi_iwi") # right_on="Property Type",
) # suffixes=("_reduced_sample", "_overall")
# )
# Which properties get done under the no EWI/IWI scenario that do not under the EWI/IWI scenario # # lodged ratings
only_no_ewi_iwi = compare[ # lodged_epc_band_comparison = reduced_sample["Lodged EPC Band"].value_counts(
(compare["total_retrofit_cost_ewi_iwi"] == 0) & # normalize=True).to_frame().reset_index().merge(
(compare["total_retrofit_cost_no_ewi_iwi"] != 0) # combined["Lodged EPC Band"].value_counts(normalize=True).to_frame().reset_index(),
] # left_on="Lodged EPC Band",
# right_on="Lodged EPC Band",
# suffixes=("_reduced_sample", "_overall")
# )
(m1["total_retrofit_cost"] > 0).sum() # # modelled ratings
(m2["total_retrofit_cost"] > 0).sum() # modelled_epc_band_comparison = reduced_sample["SAP Band"].value_counts(
# normalize=True).to_frame().reset_index().merge(
# combined["SAP Band"].value_counts(normalize=True).to_frame().reset_index(),
# left_on="SAP Band",
# right_on="SAP Band",
# suffixes=("_reduced_sample", "_overall")
# )
with_ewi_projects = compare[compare["total_retrofit_cost_no_ewi_iwi"] > 0] # # Testing measures
# m1 = pd.read_excel(
# "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no "
# "solid floor, ashp 3.0 - 20250113 final.xlsx"
# )
# m2 = pd.read_excel(
# "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no "
# "solid floor, no EWI or IWI, ashp 3.0 - 20250113 final.xlsx"
# )
z = with_ewi_projects[pd.isnull(with_ewi_projects["total_retrofit_cost_ewi_iwi"])] # compare = m1.merge(
# m2,
# left_on="uprn",
# right_on="uprn",
# suffixes=("_ewi_iwi", "_no_ewi_iwi")
# )
# # Which properties get done under the no EWI/IWI scenario that do not under the EWI/IWI scenario
# only_no_ewi_iwi = compare[
# (compare["total_retrofit_cost_ewi_iwi"] == 0) &
# (compare["total_retrofit_cost_no_ewi_iwi"] != 0)
# ]
# (m1["total_retrofit_cost"] > 0).sum()
# (m2["total_retrofit_cost"] > 0).sum()
# with_ewi_projects = compare[compare["total_retrofit_cost_no_ewi_iwi"] > 0]
# z = with_ewi_projects[pd.isnull(with_ewi_projects["total_retrofit_cost_ewi_iwi"])]

View file

@ -14,16 +14,12 @@ from collections import defaultdict
# PORTFOLIO_ID = 206 # PORTFOLIO_ID = 206
# SCENARIOS = [389] # SCENARIOS = [389]
PORTFOLIO_ID = 435 # Peabody PORTFOLIO_ID = 485 # Peabody
SCENARIOS = [ SCENARIOS = [
908, 970,
909,
910,
] ]
scenario_names = { scenario_names = {
908: "EPC C - no solid floor, ashp 3.0", 970: "EPC C - Nosolid floor, EQI, IWI",
909: "EPC C - no solid floor, no EWI or IWI, ashp 3.0",
910: "EPC B - no solid floor, no EWI, ashp 3.0"
} }