Skip to content

Your Data

Almost everything in cranalytics takes a pandas DataFrame. There are three canonical data shapes. Learn these three and you know what every workflow wants — everything else is a converter away.

Before running anything, check your frame:

import cranalytics as ca

report = ca.check(df)     # auto-detects the workflow
report.ok                 # True when the frame is valid
report.workflow           # e.g. "portfolio"
report.shape              # e.g. "loan snapshot"
report.required_columns   # what a passing frame must contain
report.issues             # a DataFrame of problems (empty when ok)

check() never raises by default — it returns a report so you can see every problem at once. Pass strict=True to raise instead, or workflow="vintage" to skip auto-detection. On the command line: cranalytics check your_data.csv.


The three shapes

Shape Grain Minimum columns Workflow check() reports
Loan snapshot one row per loan, as of a date loan_id, principal, annual_rate, term_months, start_date, status portfolio (FICO segmentation, lifetime loss, simulation) shape="loan snapshot"
Loan history one row per loan per period loan_id, principal, annual_rate, term_months, start_date, plus your target (e.g. fpf30_flag) feature-analytics (early performance, ML modeling) shape="loan history"
Rollforward aggregate one row per segment per month-on-book segment_id, month_on_book, payments, chargeoffs, outstanding_balance rollforward (readiness, flow forecasting) shape="rollforward aggregate"

Loan snapshot

One row per loan, capturing its state as of a single date. This is the "portfolio" or "loan tape" most people start with.

Loan history

One row per loan per period (a.k.a. a performance panel). A loan history is a loan snapshot observed repeatedly over time; it carries a period column and the outcome you want to model.

Rollforward aggregate

Already summarized to one row per segment per month-on-book, with the dollar flows (payments, charge-offs, balance) the rollforward engine rolls forward.


A derived shape: the vintage triangle

The vintage workflow consumes a vintage triangle — a wide grid of cumulative loss by vintage (rows) and month-on-book (columns). It is not a base shape; it is derived from a loan history.

Converting between shapes

history_to_triangle and snapshot_from_history expect a loan history that already carries a vintage cohort and a computed loss metric — the vintage/performance-panel convention cranalytics.datasets.make_mock_performance_data produces (vintage_name, mob, cumulative_loss_rate):

import cranalytics as ca
from cranalytics.datasets import make_mock_performance_data

history = make_mock_performance_data(max_mob=24)

# Loan history  ->  vintage triangle (for the vintage workflow)
triangle = ca.history_to_triangle(history)

# Loan history  ->  loan snapshot (latest period per loan)
snapshot = ca.snapshot_from_history(history)

If your loan history instead matches the loan_history_contract shape (loan_id, fund_date, as_of_date, month_on_book), it has neither a vintage cohort nor a precomputed loss rate — both require aggregation these converters deliberately don't infer. Derive those columns yourself, then pass explicit column names:

snapshot = ca.snapshot_from_history(history, period_col="month_on_book")

Both are deterministic DataFrame-to-DataFrame converters, so you can get from the data you have to the shape a workflow needs without reverse-engineering internals.


For the exact column types, accepted values, and aliases each contract enforces, see the Input Data Contracts reference. This page is the friendly front door; that page is the detailed spec.