Source code for openpois.models.apply
# -------------------------------------------------------------
# Copyright (c) Henry Spatial Analysis. All rights reserved.
# Licensed under the MIT License. See LICENSE in project root for information.
# -------------------------------------------------------------
"""
Utilities for applying fitted change-rate model predictions to a POI snapshot.
Provides functions to load saved predictions and build fast numpy lookup arrays
for both constant and random-effects model variants.
"""
from __future__ import annotations
from pathlib import Path
import numpy as np
import pandas as pd
PREDICTIONS_FILE = "predictions.csv"
[docs]
def load_predictions(version_dir: Path) -> pd.DataFrame:
"""
Load predictions.csv from a model version directory.
Adds a ``t2_int`` column (t2 * 10, rounded to int) as an integer lookup key.
Args:
version_dir: Path to the versioned model output directory containing
``predictions.csv``.
Returns:
DataFrame with columns t1, t2, p_mean, p_lower, p_upper, units, t2_int,
and optionally group / group_name for random-effects models.
"""
df = pd.read_csv(version_dir / PREDICTIONS_FILE)
df["t2_int"] = (df["t2"] * 10).round().astype(int)
return df
[docs]
def constant_lookup(pred_df: pd.DataFrame) -> np.ndarray:
"""
Build a (101, 3) float64 lookup array for a constant model.
Row index = t2_int (0–100); columns = [p_mean, p_lower, p_upper].
Args:
pred_df: Predictions DataFrame returned by ``load_predictions``.
Returns:
Array of shape (101, 3).
"""
arr = np.full((101, 3), np.nan)
idx = pred_df["t2_int"].to_numpy()
arr[idx] = pred_df[["p_mean", "p_lower", "p_upper"]].to_numpy()
return arr
[docs]
def group_lookup(pred_df: pd.DataFrame) -> tuple[list[str], np.ndarray]:
"""
Build a (n_groups, 101, 3) float64 lookup array for a random-effects model.
First axis = group index (sorted alphabetically); second = t2_int (0–100);
third = [p_mean, p_lower, p_upper].
Args:
pred_df: Predictions DataFrame returned by ``load_predictions``.
Must contain a ``group_name`` column.
Returns:
Tuple of (ordered_group_names, array of shape (n_groups, 101, 3)).
"""
groups = sorted(pred_df["group_name"].unique())
n_groups = len(groups)
arr = np.full((n_groups, 101, 3), np.nan)
for ci, col in enumerate(["p_mean", "p_lower", "p_upper"]):
pivot = (
pred_df
.pivot(index = "group_name", columns = "t2_int", values = col)
.reindex(index = groups, columns = range(101))
)
arr[:, :, ci] = pivot.to_numpy()
return groups, arr