Source code for experiencestudies.banding

"""Banded experience summaries.

Assign rows to size bands (the :func:`~actuarialpy.assign_band` primitive lives
in ``actuarialpy``) and then summarize experience within each band. Band edges
are always a parameter, since different analyses use different cut points.
"""

from __future__ import annotations

from collections.abc import Iterable, Sequence

import pandas as pd

from actuarialpy.banding import assign_band
from experiencestudies.experience import summarize_experience


[docs] def summarize_by_band( df: pd.DataFrame, value_col: str, bands: Sequence[float], *, labels: Sequence[str] | None = None, expense_cols: str | Iterable[str], revenue_cols: str | Iterable[str], exposure_cols: str | Iterable[str] | None = None, band_col: str = "band", ratio_col: str | None = None, right: bool = False, profile: str | None = None, ) -> pd.DataFrame: """Assign size bands then summarize experience grouped by band. Returns one row per band in band order (empty bands included), with the same aggregates, loss ratio, and per-exposure metrics as :func:`~experiencestudies.summarize_experience`. """ banded = assign_band( df, value_col, bands, labels=labels, band_col=band_col, right=right, copy=True, ) summary = summarize_experience( banded, groupby=band_col, expense_cols=expense_cols, revenue_cols=revenue_cols, exposure_cols=exposure_cols, ratio_col=ratio_col, profile=profile, ) # Preserve band order and surface empty bands explicitly. order = list(banded[band_col].cat.categories) summary[band_col] = pd.Categorical(summary[band_col], categories=order, ordered=True) return summary.sort_values(band_col).reset_index(drop=True)