pippen.data.schemas¶
Validates the shape of every table at the point of ingest, before a bad file reaches any calculation.
A column that silently changes dtype between two seasons will not stop the solver from printing an answer. It stops the answer from being right, and nothing else in the pipeline would say so.
pippen.data.schemas ¶
pandera schemas for every table this project ingests.
A downstream regression cannot tell a malformed download from a bad season. If a column silently changes dtype between two seasons' Parquet files, or a required identifier goes missing for a handful of rows, the RAPM solver or the reliability measurement will still run and will still print an answer. The answer will be wrong and nothing will say so. These schemas exist to fail loudly at the point of ingest, before a bad file reaches any calculation.
Known limitation, load-bearing for the rest of the pipeline
The play_by_play table validated here is ESPN-sourced, via hoopR. It
records event participants only (athlete_id_1/2/3) and carries
no on-court lineup column. RAPM needs the full five-man lineup for both
teams on every possession, so it cannot be computed from this table, no
matter how clean a copy of it passes validation. That requires
pbpstats running against NBA API data instead. This module checks the
shape of the data; it makes no claim about what can be computed from it.
Schema source and confidence
Every schema below has now been checked against a real hoopR file. Doing so
corrected two of them. player_box has no percentage column at all, only
made and attempted, and schedules names its teams home_id and
away_id rather than following the play-by-play naming. Both had been
guessed from convention and both guesses were wrong, which is the argument
for checking a schema against a sample rather than against documentation.
Each schema declares a core rather than every column. The real files carry
57 to 78 columns; what is declared here is what this project depends on.
``strict=False`` lets the rest through untouched.
Strictness
Every schema below sets strict=False. hoopR adds columns to its
published tables over time, and a hard failure the day the publisher adds
one would break every scheduled refresh for a reason that has nothing to
do with data quality. strict=False lets unrecognised columns pass
through untouched rather than raising or silently dropping them. Dropping
(strict="filter") was considered and rejected: a discarded column
leaves no trace, and a future stage that starts to depend on it would fail
somewhere downstream instead of here.
Coercion
Every schema also sets coerce=True. One season's file read as
int32 and another's as int64 for the same column is a real,
observed source of silent divergence: a join or a concatenation between
the two can produce upcasting, duplication, or a dtype-driven mismatch
that never raises. Coercing every declared column to its schema dtype
means every season leaves validation in the same dtype, or validation
fails and says which column would not coerce.
SchemaValidationError ¶
Bases: ValueError
A table failed schema validation.
Raised by :func:validate with every failing row and check already
collected, rather than only the first one, so a human fixes the file once
instead of re-running validation after every single fix.
Source code in src/pippen/data/schemas.py
get_schema ¶
Return the pandera schema for one dataset, by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset
|
str
|
Dataset name, e.g. |
required |
Returns:
| Type | Description |
|---|---|
DataFrameSchema
|
The schema registered for |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/pippen/data/schemas.py
validate ¶
Validate a table against its schema and return the validated copy.
Validation is lazy: every failing column and check is collected before raising, instead of stopping at the first one. Coercion happens as part of validation, so the returned frame's dtypes match the schema even when the input's did not.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
DataFrame
|
The table to validate. |
required |
dataset
|
str
|
Dataset name identifying which schema to check against, e.g.
|
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
DataFrame
|
Columns not declared in the schema are passed through unchanged. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
SchemaValidationError
|
If |