TableSource#
TableSource loads an .ltk actuarial table file from disk and
exposes the raw decrement arrays and metadata for use by LifeTable,
DisabilityTable, and ExitTable constructors
(each constructor delegates to TableSource internally).
Table files are located in the directory configured by
tables_path (default: absolute path to actuarial_tables/
in the working directory at the time of the first Config() call). A disk-read
cache keyed on file path and modification time avoids redundant I/O for repeated
access to the same table within a session.
Note
TableSource is primarily an internal component. Users normally access table
data through LifeTable and its siblings rather than constructing
a TableSource directly.
Bundled catalogue tables are shipped in-repo as Python payloads; install them to
tables_path as .ltk files with Tables.install() (import
Tables from lactuca.tables.data) before first use — see
Bundled Actuarial Tables.
See also
Using Actuarial Tables — Loading and inspecting tables.
Bundled Actuarial Tables — Tables bundled with Lactuca.
- class lactuca.TableSource(file_name: str | PathLike[str], path: str | PathLike[str] | None = None)#
Bases:
objectLoads an actuarial table (
.ltk) and exposes its data and metadata as properties.All metadata fields (except
"decrement_scale_factor"and"mi_scale_factor") are exposed as read-only properties. All attributes are set at initialisation time. If any required metadata field is missing, aValueErroris raised.See also
DecrementTableHigher-level actuarial table API built on top of TableSource.
Examples
>>> from lactuca import TableSource >>> ts = TableSource("PER2020_Ind_1o.ltk") >>> ts.table_name 'PER2020_Ind_1o' >>> ts.omega 110
- head(n: int = 10, include_age: bool = True, show_normalized: bool = False) DataFrame#
Return the first n rows of the table data, optionally excluding normalized padding.
By default, shows first n rows from meaningful data (starting at
start_age). Useshow_normalized=Trueto include padding rows from age 0.- Parameters:
n (int, default 10) – Number of rows to return from the start.
include_age (bool, default True) – If
True, include'age'column. IfFalse, exclude'age'column from output.show_normalized (bool, default False) – If
True, start from age 0 (show padding if present). IfFalse, start fromstart_age(exclude padding).
- Returns:
The first n rows with or without age column.
- Return type:
polars.DataFrame
See also
TableSource.tailView last n rows.
TableSource.view_dataView full table data.
Examples
>>> from lactuca import TableSource >>> ts = TableSource("GAM71.ltk") >>> print(ts.head(3)) # Shows ages 5, 6, 7 >>> print(ts.head(3, show_normalized=True)) # Shows ages 0, 1, 2 (padding)
- tail(n: int = 10, include_age: bool = True, show_normalized: bool = False) DataFrame#
Return the last n rows of the table data, always ending at
omega.Use the
show_normalizedparameter to control which range is considered.- Parameters:
n (int, default 10) – Number of rows to return from the end.
include_age (bool, default True) – If
True, include'age'column. IfFalse, exclude'age'column from output.show_normalized (bool, default False) – If
True, consider full normalized range (0 toomega). IfFalse, consider only meaningful range (start_agetoomega).
- Returns:
The last n rows with or without age column.
- Return type:
polars.DataFrame
See also
TableSource.headView first n rows.
TableSource.view_dataView full table data.
Examples
>>> from lactuca import TableSource >>> ts = TableSource("GAM71.ltk") >>> print(ts.tail(3)) # Shows ages 108, 109, 110
- to_dict() dict[str, Any]#
Return a dictionary containing the main attributes and metadata of the table.
- Returns:
Dictionary with the following top-level keys:
'file_name'(str): base name of the.ltkfile.'file_path'(str): absolute POSIX path of the.ltkfile.'w'(int): current terminal age (effective \(\omega\) after any modifications).'columns'(list[str]): DataFrame column names.'start_duration'(int or None): minimum valid integer duration for select-ultimate tables (0for CMI/UK convention,1for the standard convention);Nonefor non-select tables. Auto-detected from the minimum_s{k}column suffix at load time — not stored in the.ltkfile.'metadata'(dict): raw file metadata with parsed Python-typed values:'valid_sexes'aslist,'sex_independent'/'generational'asbool, scale factors asintorfloat.'data'(polars.DataFrame): full table data.
- Return type:
dict
Examples
>>> from lactuca import TableSource >>> ts = TableSource("PER2020_Ind_1o.ltk") >>> d = ts.to_dict() >>> d["file_name"] 'PER2020_Ind_1o.ltk' >>> list(d.keys()) ['file_name', 'file_path', 'w', 'columns', 'start_duration', 'metadata', 'data']
See also
TableSource.to_payloadMinimal serializable payload for table reconstruction.
- to_payload() dict[str, object]#
Return a minimal serializable payload sufficient to recreate the table via
TableBuilder(payload.pop("data"), **payload).Data arrays start at
start_age(no zero-padding rows).Scale factors reflect the applied values (e.g. 1000 if data was scaled by 1000 before storage), so that a round-trip
TableBuilderreceives the correct scale and reconstructs identical data.- Returns:
Serializable dict with keys
'table_name','table_type','generational','omega','start_age','sex_independent','description','decrement_scale_factor', and'data'(adictof column lists starting atstart_age). Optionally includes'select','select_period','base_year','generational_formula_type','grid_years', and'mi_scale_factor'when applicable.- Return type:
dict
Examples
>>> from lactuca import TableSource >>> ts = TableSource("PER2020_Ind_1o.ltk") >>> payload = ts.to_payload() >>> payload["table_name"] 'PER2020_Ind_1o' >>> "data" in payload True
See also
TableSource.to_dictFull dictionary including the Polars DataFrame.
- view_data(include_age: bool = True, show_normalized: bool = False) DataFrame#
Return the full table data, optionally excluding normalized padding rows.
By default, shows only meaningful data (excludes ages below
start_age). Useshow_normalized=Trueto see all rows including internal padding.- Parameters:
- Returns:
Table data with or without age column.
- Return type:
polars.DataFrame
See also
TableSource.headView first n rows.
TableSource.tailView last n rows.
TableSource.start_ageStarting age from original table definition.
Examples
View GAM71 data (start_age=5):
>>> from lactuca import TableSource >>> ts = TableSource("GAM71.ltk") >>> df = ts.view_data() # Shows ages 5-110 (106 rows) >>> df_full = ts.view_data(show_normalized=True) # Shows ages 0-110 (111 rows)
- property base_year: int | None#
Base year for generational improvement calculations.
The base year is the reference period at which the decrement rates stored in the table apply without any improvement adjustment. Cohort calculations project rates forward or backward from this year using the improvement factors in the
mi_columns.- Returns:
Base year as defined in the table metadata, or
Nonefor static period tables.- Return type:
int or None
See also
TableSource.generationalWhether the table applies cohort improvement.
TableSource.generational_formula_typeFormula type for improvement calculations.
TableSource.grid_yearsProjection grid years (for
'projected_improvement'tables).
- property data: DataFrame#
Table data as a Polars DataFrame, covering all ages from 0 to
omega.The
'age'column (integers \(0\) to \(\omega\)) is generated at load time and is always the first column; it is not stored in the.ltkfile. Rows belowstart_ageare zero-padded. All remaining columns depend on the table type and structure:Aggregate tables:
qx_m,qx_f(life);ix_m,ix_f(disability);ox_m,ox_f(exit).Select-ultimate tables:
qx_m_s1, …,qx_m_s{n},qx_m_ult, and the corresponding_fvariants.Generational tables add
mi_improvement columns:mi_m,mi_f(flat structure);mi_m_YYYY,mi_f_YYYY(year-indexed / projected);mi_m_s1,mi_m_ult, … (select-period structure).
- Returns:
Full table data including the
'age'column and all decrement/improvement columns.- Return type:
polars.DataFrame
See also
TableSource.metadataRaw metadata dictionary.
TableSource.view_dataFiltered view excluding zero-padding rows below
start_age.
- property description: str#
Description of the table from metadata.
- Returns:
Human-readable description string, or an empty string if not provided in the
.ltkfile.- Return type:
str
See also
TableSource.table_nameName of the table as defined in the file metadata.
TableSource.metadataRaw metadata dictionary including the description field.
- property file_name: str#
Basename of the loaded table file (e.g.
'PER2020.ltk').- Returns:
Base filename including the
.ltkextension.- Return type:
str
See also
TableSource.file_pathFull resolved path to the loaded table file.
- property file_path: Path#
Full resolved path to the loaded table file.
- Returns:
Absolute path to the
.ltkfile as apathlib.Pathobject.- Return type:
pathlib.Path
See also
TableSource.file_nameBasename of the loaded table file.
- property generational: bool#
Whether the table applies generational (cohort) improvement factors.
Determined by the
generationalfield in the table metadata.- Returns:
Truefor generational (cohort) tables;Falsefor static period tables.- Return type:
bool
See also
TableSource.generational_formula_typeFormula type for cohort-improvement calculations.
- property generational_formula_type: Literal['exponential_improvement', 'linear_improvement', 'discrete_improvement', 'projected_improvement'] | None#
Formula type used for generational (cohort) improvement calculations.
- Returns:
One of
'exponential_improvement','linear_improvement','discrete_improvement', or'projected_improvement'; orNonefor non-generational tables.- Return type:
GenerationalFormulaTypeLiteral or None
See also
TableSource.generationalWhether the table applies generational improvement factors.
- property grid_years: list[int] | None#
Sorted list of projection grid years for
projected_improvementtables.These are the years for which year-indexed mi columns (
mi_{sex}_YYYY) are stored in the table. For other formula types, returnsNone.- Returns:
Sorted list of grid years (e.g.
[2021, 2022, ..., 2036]), orNoneif the table is not a period-projection table.- Return type:
list[int] or None
See also
TableSource.generational_formula_typeFormula type for cohort improvement calculations.
TableSource.base_yearReference year for improvement calculations.
- property metadata: dict[str, Any]#
Raw metadata dictionary loaded from the
.ltkfile.All values are normalized string metadata as loaded from the table file. For type-safe access to individual fields, prefer the corresponding typed properties (e.g.
omega,table_type,generational,valid_sexes).- Returns:
Shallow copy of metadata key-value pairs as loaded from the table file.
- Return type:
dict[str, Any]
See also
TableSource.omegaParsed terminal age (integer).
TableSource.table_typeParsed table type string.
TableSource.generationalParsed generational flag (bool).
TableSource.to_dictReturns parsed metadata together with the table data.
- property mi_by_duration: bool#
Whether improvement factors vary by select duration.
Trueonly whenmi_structureis'select_period', i.e. the table stores separate improvement columns per select duration (e.g.mi_m_s1,mi_m_ult).- Returns:
Trueif per-duration MI columns are present;Falseotherwise.- Return type:
bool
See also
TableSource.mi_structureLayout tag for mortality-improvement columns.
- property mi_structure: str | None#
Layout tag for mortality-improvement columns.
Identifies the column layout used to store improvement factors:
'flat': a single improvement column per sex (mi_m,mi_f), shared across all ages and durations.'year_indexed': per-year columns per sex (mi_m_YYYY,mi_f_YYYY), one column per projection year ingrid_years.'select_period': per-duration columns per sex (mi_m_s1, …,mi_m_ult), one column per select duration.
- Returns:
One of
'flat','year_indexed', or'select_period'for generational tables;Nonefor non-generational tables.- Return type:
str or None
See also
TableSource.mi_by_durationWhether improvement factors vary by select duration.
- property omega: int#
Terminal age from table metadata (immutable).
\(\omega\) is the terminal age defined in the original table. For a table covering ages \(0\) to \(118\), \(\omega = 118\). All decrement arrays in the original table have length \(\omega + 1\).
This value never changes, even if the table is modified. Use the
wproperty for the current effective terminal age (may change after modifications inDecrementTable).- Returns:
Terminal age \(\omega\) as defined in the table metadata.
- Return type:
int
See also
TableSource.wCurrent effective terminal age (always equal to
omegainTableSource).
Examples
>>> from lactuca import TableSource >>> ts = TableSource("PER2020_Ind_1o.ltk") >>> ts.omega # Terminal age defined in the .ltk metadata 110 >>> ts.omega == ts.w # Always True in TableSource True
- property select: bool#
Whether this is a select-ultimate table.
- Returns:
Trueif the table contains select-duration columns (e.g.qx_m_s1,qx_m_ult);Falsefor aggregate tables.- Return type:
bool
See also
TableSource.select_periodNumber of select-duration years.
- property select_improvement_diagonal: str | None#
Calendar-year index used for mortality improvement on select columns.
For generational select-ultimate tables, improvement factors are looked up on a cohort diagonal. The index depends on
generational_formula_type:'projected_improvement'→'cohort_plus_x_plus_d'(calendar year $t = text{cohort} + x + d$, implemented aseffective_cohort = cohort + d).All other generational formulas →
'cohort_plus_x'(calendar year $t = text{cohort} + x$; select duration $d$ affects only the base $q$ column, not the improvement diagonal).
- Returns:
'cohort_plus_x_plus_d','cohort_plus_x', orNonewhen the table is not generational or not select-ultimate.- Return type:
str or None
See also
TableSource.generational_formula_typeDispatches the diagonal convention.
TableSource.selectWhether select-duration columns are present.
- property select_period: int | None#
Select period in years (
Nonefor non-select tables).- Returns:
Number of select-duration years, or
Nonefor non-select tables.- Return type:
int or None
Notes
As defined in the table metadata; represents the number of select-duration years (e.g.
s1,s2for a 2-year select period), excluding the ultimate (ult) column. For a table with duration keys{1, 2, 'ult'},select_periodis2.See also
TableSource.selectWhether this is a select-ultimate table.
- property sex_independent: bool#
Whether this table has identical rates for both sexes.
When
True, the table uses the same mortality/disability/exit rates for males and females (e.g., IASS-90, SS90-TOT, SS90-ABS). At load time, a single-sex column is automatically mirrored to the other sex so that both_mand_fcolumns are always present.- Returns:
Trueif rates are sex-independent;Falseotherwise.- Return type:
bool
See also
TableSource.valid_sexesSex codes available in this table.
- property start_age: int#
Starting age of the table from original source data.
Returns the age at which the table was originally defined to start. For example, GAM71 starts at age 5, GAM94 starts at age 1.
Although tables are internally normalized to age 0 (with padding for ages below the original start), this property returns the meaningful starting age from the design of the table.
- Returns:
Starting age from original table definition (0 if table started at age 0).
- Return type:
int
See also
TableSource.omegaTerminal age of the table.
TableSource.view_dataBy default excludes padding rows below
start_age.
Examples
>>> from lactuca import TableSource >>> ts = TableSource("GAM71.ltk") >>> ts.start_age # Original table starts at age 5 5 >>> ts_gam83 = TableSource("GAM83.ltk") >>> ts_gam83.start_age # Original table starts at age 0 0
- property start_duration: int | None#
First (minimum) integer duration in the select columns, or
Nonefor non-select tables.- Returns:
0for CMI/UK tables (AM92, AF92 — Duration-0 convention),1for most other select tables (Duration-1 convention), orNoneif this is not a select table.- Return type:
int or None
Notes
Auto-detected at load time by scanning DataFrame columns for the minimum
_s{k}suffix index.See also
TableSource.selectWhether this is a select-ultimate table.
TableSource.select_periodNumber of select-duration years.
- property table_name: str#
Name of the table as defined in the file metadata.
- Returns:
Table name string as stored in the table metadata (e.g.
'PER2020_Ind_1o').- Return type:
str
See also
TableSource.table_typeType of the table (life, disability, or exit).
- property table_type: Literal['life', 'disability', 'exit']#
Type of the table from metadata.
- Returns:
One of
'life','disability', or'exit'.- Return type:
TableTypeLiteral
See also
TableSource.table_nameName of the table.
- property valid_sexes: list[str]#
Sex codes for which this table provides decrement rates.
Code
'm'maps toqx_m/ix_m/ox_mcolumns; code'f'maps toqx_f/ix_f/ox_fcolumns. For sex-independent tables both codes are always present, even if the source file contained data for only one sex. The unisex code'u'is handled byDecrementTableand is not stored here.- Returns:
New list of sex codes (e.g.
['m', 'f']) on every call.- Return type:
list[str]
See also
TableSource.sex_independentWhether rates are identical for both sexes.
- property w: int#
Current effective terminal age (may differ from
omegaafter modifications).omegais the immutable terminal age read from the.ltkfile and never changes.wstarts equal toomegabut is updated whenever the decrement array is replaced by callingmodify_qx,modify_ix, ormodify_oxon aDecrementTableinstance. After such a call,wequals the last valid index of the new array, which may be larger or smaller than the originalomega.All actuarial outputs — life tables, commutation functions, present values, and annuities — use
was their upper age bound. Always preferwoveromegain internal calculations.In
TableSourceitselfwalways equalsomegabecause no modifications have been applied yet.- Returns:
Current effective terminal age.
- Return type:
int
See also
TableSource.omegaImmutable terminal age from table metadata
DecrementTable.modify_qxReplace the mortality array and update
w.DisabilityTable.modify_ixReplace the disability array and update
w.ExitTable.modify_oxReplace the exit array and update
w.