Skip to main content
Version: 0.1.5

WNBA — additional Python functions — Analytics

make_prob_by_context​

make_prob_by_context(ptshots: 'pl.DataFrame', *, return_as_pandas: 'bool' = False) -> "'dict[str, Union[pl.DataFrame, pd.DataFrame]]'"

Marginal FG% tables by defender distance and by shot clock.

The public API exposes defender-distance and shot-clock only as aggregate bucket tables (playerdashptshots), not per-shot fields, so this aggregates Σfgm/Σfga across players within each bucket.

Parameters

ParameterTypeDefaultDescription
ptshotsDataFrameThe stacked playerdashptshots fixture — one frame with a result_set tag (ClosestDefenderShooting / ShotClockShooting) plus bucket, fga, fgm.
return_as_pandasboolFalseReturn pandas DataFrames instead of polars.

Returns

{"defender": frame, "shot_clock": frame} each with rows per bucket (bucket, fga, fgm, fg_pct). Missing result sets return the zero-row schema.

Example

from sportsdataverse.nba.nba_shot_value import make_prob_by_context
tables = make_prob_by_context(ptshots)
tables["defender"].sort("fg_pct")

make_prob_joint​

make_prob_joint(defender: 'pl.DataFrame', shot_clock: 'pl.DataFrame', overall_fg_pct: 'float', *, return_as_pandas: 'bool' = False) -> "'Union[pl.DataFrame, pd.DataFrame]'"

Independence-combined defender x shot-clock make probability.

Combines the two marginal FG% tables under a conditional-independence assumption via odds multipliers: odds(p) = p/(1-p); odds_joint = odds_overall * (odds_def/odds_overall) * (odds_clock/odds_overall); joint = odds_joint/(1+odds_joint). This assumes defender distance and shot-clock effects are independent given the league baseline — a simplification (a late clock correlates with tighter defense), documented here so callers weigh it.

Parameters

ParameterTypeDefaultDescription
defenderDataFrameThe "defender" marginal table from make_prob_by_context (bucket, fg_pct).
shot_clockDataFrameThe "shot_clock" marginal table (bucket, fg_pct).
overall_fg_pctfloatThe league overall FG% baseline.
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

One row per (close_def_dist_range, shot_clock_range): close_def_dist_range:Utf8, shot_clock_range:Utf8, joint_fg_pct:Float64. Empty inputs return the zero-row schema.

No returns table is published for this function: no capture: its inputs come from make_prob_by_context on stats.nba.com tracking data, which answers HTTP 403 to the datacenter IP the docs are built on.

Example

from sportsdataverse.nba.nba_shot_value import make_prob_by_context, make_prob_joint
t = make_prob_by_context(ptshots)
joint = make_prob_joint(t["defender"], t["shot_clock"], 0.47)

score_shot_xpoints​

score_shot_xpoints(shots: 'pl.DataFrame', league_avgs: 'pl.DataFrame', *, return_as_pandas: 'bool' = False) -> "'Union[pl.DataFrame, pd.DataFrame]'"

Score each shot with expected points from the league-average baseline.

Joins the per-shot frame to the zone baseline (falling back to the within-shot_zone_range mean when a zone triple is unmatched) and adds shot_value (3 for a 3PT shot else 2), xpoints = base_fg_pct * shot_value, and actual_points = shot_made_flag * shot_value.

Parameters

ParameterTypeDefaultDescription
shotsDataFramePer-shot Shot_Chart_Detail frame (needs shot_type + the three zone keys + shot_made_flag).
league_avgsDataFrameThe LeagueAverages frame (see xpoints_baseline).
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

The input shots plus shot_value:Int64, base_fg_pct:Float64, xpoints:Float64, actual_points:Float64. Empty input returns the augmented schema with zero rows.

No returns table is published for this function: no capture: its input is the shots frame of wnba_shot_value, which reads stats.nba.com shotchartdetail; that host answers HTTP 403 to the datacenter IP the docs are built on.

Example

from sportsdataverse.nba.nba_shot_value import score_shot_xpoints
scored = score_shot_xpoints(shots, league_avgs)

# Pipeline next step (one line)

scored.group_by("player_id").agg(pl.col("xpoints").sum())

shooter_talent​

shooter_talent(scored_shots: 'pl.DataFrame', *, league_id: 'str' = '00', min_attempts: 'int' = 50, return_as_pandas: 'bool' = False) -> "'Union[pl.DataFrame, pd.DataFrame]'"

Regressed shooter true-talent: make%-above-expected, shrunk to the mean.

Aggregates score_shot_xpoints output per shooter and regresses the raw over-expected rate toward zero by n/(n+k) (k = get_shrinkage_k(league_id), fitted split-half). As-of leakage boundary: to score a shooter's talent for shots after date D, pass only that shooter's shots before D -- this function does not enforce the cut itself.

Parameters

ParameterTypeDefaultDescription
scored_shotsDataFramescore_shot_xpoints output (needs player_id, shot_made_flag, base_fg_pct, xpoints, actual_points).
league_idstr'00'"00" NBA, "10" WNBA, "20" G-League.
min_attemptsint50Drop shooters with fewer attempts (unstable estimate).
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

One row per player_id: player_id:Int64, n_att:Int64, actual_makes:Int64, exp_makes:Float64, points_above_expected:Float64, raw_above_pct:Float64, talent_pct:Float64. Empty input returns the zero-row schema.

No returns table is published for this function: no capture: its input is the shots frame of wnba_shot_value, which reads stats.nba.com shotchartdetail; that host answers HTTP 403 to the datacenter IP the docs are built on.

Example

from sportsdataverse.nba.nba_shot_value import score_shot_xpoints, shooter_talent
talent = shooter_talent(score_shot_xpoints(shots, league_avgs))

# Pipeline next step (one line)

talent.sort("talent_pct", descending=True).head(15)

shot_selection_quality​

shot_selection_quality(scored_shots: 'pl.DataFrame', *, min_attempts: 'int' = 50, return_as_pandas: 'bool' = False) -> "'Union[pl.DataFrame, pd.DataFrame]'"

Player shot-selection quality: mean expected value vs the league mean.

xev_per_shot is a player's mean xpoints (the value of the LOOKS they take, independent of makes); selection_quality is that minus the league-wide mean xpoints over the same frame -- a rim-and-three diet scores positive, a mid-range diet negative.

Parameters

ParameterTypeDefaultDescription
scored_shotsDataFramescore_shot_xpoints output (needs player_id, xpoints).
min_attemptsint50Drop players with fewer attempts.
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

One row per player_id: player_id:Int64, n_att:Int64, xev_per_shot:Float64, league_xev_per_shot:Float64, selection_quality:Float64. Empty input returns the zero-row schema.

No returns table is published for this function: no capture: its input is the shots frame of wnba_shot_value, which reads stats.nba.com shotchartdetail; that host answers HTTP 403 to the datacenter IP the docs are built on.

Example

from sportsdataverse.nba.nba_shot_value import score_shot_xpoints, shot_selection_quality
sel = shot_selection_quality(score_shot_xpoints(shots, league_avgs))

# Pipeline next step (one line)

sel.sort("selection_quality", descending=True).head(15)

wnba_availability​

wnba_availability(seasons: "'int | list[int]'", *, return_as_pandas: 'bool' = False) -> "'pl.DataFrame | pd.DataFrame'"

WNBA availability -- the NBA core bound to league="wnba".

See sportsdataverse.nba.nba_availability.nba_availability for the full contract; avail_pct is availability, not skill.

Parameters

ParameterTypeDefaultDescription
seasonsint | list[int]A season (start year) or list of seasons.
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

Frame player_id:Utf8, season:Int64, avail_pct:Float64.

No returns table is published for this function: no capture: it reads stats.wnba.com, which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_availability
proj = wnba_availability(2023)

wnba_expected_turnovers​

wnba_expected_turnovers(season: 'str', *, base: "'Optional[pl.DataFrame]'" = None, player_mix: "'Optional[pl.DataFrame]'" = None, return_as_pandas: 'bool' = False) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA expected turnovers / ball-security skill (league_id="10").

Thin wrapper binding sportsdataverse.nba.nba_expected_turnovers.nba_expected_turnovers to the women's league.

Parameters

ParameterTypeDefaultDescription
seasonstrSeason string, e.g. "2024".
baseOptional[DataFrame]NoneInjected nba_stats_leaguedashplayerstats (Base) frame.
player_mixOptional[DataFrame]NoneInjected Synergy player-level offensive mix.
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

Same schema as sportsdataverse.nba.nba_expected_turnovers.nba_expected_turnovers.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_expected_turnovers
t = wnba_expected_turnovers("2024")
print(t.sort("ball_security_skill", descending=True).head())

wnba_foul_drawing​

wnba_foul_drawing(season: 'str', *, base: "'Optional[pl.DataFrame]'" = None, advanced: "'Optional[pl.DataFrame]'" = None, player_mix: "'Optional[pl.DataFrame]'" = None, return_as_pandas: 'bool' = False) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA foul-drawing / FT-generation (league_id="10").

Thin wrapper binding sportsdataverse.nba.nba_foul_drawing.nba_foul_drawing to the women's league.

Parameters

ParameterTypeDefaultDescription
seasonstrSeason string, e.g. "2024".
baseOptional[DataFrame]NoneInjected nba_stats_leaguedashplayerstats (Base) frame.
advancedOptional[DataFrame]NoneInjected Advanced-measure frame.
player_mixOptional[DataFrame]NoneInjected Synergy player-level offensive mix.
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

Same schema as sportsdataverse.nba.nba_foul_drawing.nba_foul_drawing.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_foul_drawing
f = wnba_foul_drawing("2024")
print(f.sort("foul_draw_skill", descending=True).head())

wnba_matchup_drapm​

wnba_matchup_drapm(season: 'str', *, matchups: "'Optional[pl.DataFrame]'" = None, config: "'Optional[PlaytypeConfig]'" = None, return_as_pandas: 'bool' = False) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA matchup defensive RAPM (league_id="10").

Thin wrapper binding sportsdataverse.nba.nba_matchup_drapm.nba_matchup_drapm to the women's league.

Parameters

ParameterTypeDefaultDescription
seasonstrSeason string, e.g. "2024".
matchupsOptional[DataFrame]NoneInjected nba_stats_leagueseasonmatchups-shaped frame.
configOptional[PlaytypeConfig]None~sportsdataverse.nba.nba_playtype_constants.PlaytypeConfig override.
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

Same schema as sportsdataverse.nba.nba_matchup_drapm.nba_matchup_drapm.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_matchup_drapm
d = wnba_matchup_drapm("2024")
print(d.sort("matchup_drapm", descending=True).head())

wnba_player_props​

wnba_player_props(season: 'int', game_id: 'str', home_team_id: 'str', away_team_id: 'str', *, league_id: 'str' = '00', return_as_pandas: 'bool' = False) -> 'Union[pl.DataFrame, pd.DataFrame]'

WNBA player props (league_id='10'). See sportsdataverse.nba.nba_player_props.nba_player_props.

Parameters

ParameterTypeDefaultDescription
seasonint
game_idstr
home_team_idstr
away_team_idstr
league_idstr'00'
return_as_pandasboolFalse

Returns

One row per player on either team: player_id, team_id, stat_pts_exp, stat_reb_exp, stat_ast_exp, stat_fg3m_exp, pace_proj. Empty input returns that schema with zero rows.

col_nametypedescription
player_idcharacterUnique player identifier.
team_idcharacterUnique team identifier.
stat_pts_expdouble
stat_reb_expdouble
stat_ast_expdouble
stat_fg3m_expdouble
pace_projdouble

wnba_playtype_ratings​

wnba_playtype_ratings(season: 'str', *, off_team: "'Optional[pl.DataFrame]'" = None, def_team: "'Optional[pl.DataFrame]'" = None, schedule: "'Optional[pl.DataFrame]'" = None, return_as_pandas: 'bool' = False) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA Synergy play-type-adjusted offense/defense (league_id="10").

Thin wrapper binding sportsdataverse.nba.nba_playtype.nba_playtype_ratings to the women's league. Synergy coverage is sparse for the WNBA; an empty upstream fetch degrades to a zero-row frame (never raises).

Parameters

ParameterTypeDefaultDescription
seasonstrSeason string, e.g. "2024".
off_teamOptional[DataFrame]NoneInjected Synergy offensive team frame (bypasses the live fetch).
def_teamOptional[DataFrame]NoneInjected Synergy defensive team frame.
scheduleOptional[DataFrame]NoneInjected team_id/opp_team_id schedule frame.
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

Same schema as sportsdataverse.nba.nba_playtype.nba_playtype_ratings.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_playtype_ratings
r = wnba_playtype_ratings("2024")
print(r.sort("adj_off", descending=True).head())

wnba_referee_assignments​

wnba_referee_assignments(date: 'str | _dt.date', *, raw: 'bool' = False, return_as_pandas: 'bool' = False, proxy: 'dict | None' = None) -> 'dict[str, Any]'

Fetch and parse WNBA referee assignments for a given date from official.nba.com.

Retrieves the referee crew assignments and replay center officials for all WNBA games on a given date. The crew_position column (1–4) represents the feed's slot order; slot 1 is inferred to be the crew chief. The season column is the WNBA single-year season (feed year converted as-is). This is a thin shim over sportsdataverse.nba.nba_officiating.nba_referee_assignments that sets league="wnba".

Parameters

ParameterTypeDefaultDescription
datestr | dateThe date to fetch assignments for (str in "YYYY-MM-DD" format or datetime.date).
rawboolFalseIf True, return the raw JSON payload (dict) with all three leagues instead of parsed DataFrames.
return_as_pandasboolFalseIf True, return pandas DataFrames instead of polars.
proxydict | NoneNoneOptional proxy dict passed through to the HTTP layer.

Returns

A dict with keys "officials" and "replay_center" mapping to DataFrames. If raw=True, returns the full three-league JSON payload instead.

col_nametypedescription
officials.leaguecharacterLeague the assignment belongs to: nba, gl (G League), or wnba.
officials.game_idcharacter10-digit game id (zero-padded) for the assigned game.
officials.game_datedateGame date parsed from the feed's MM/DD/YYYY format.
officials.seasonintegerSeason end year, converted from the feed's code: start year + 1 for NBA/G League's two-calendar-year seasons, start year unchanged for WNBA's single-year seasons.
officials.season_typecharacterSeason type decoded from the feed's season code first digit: preseason, regular, all-star, playoffs, play-in, or nba-cup-final.
officials.game_codecharacterLeague game code in YYYYMMDD/AWYHOM format, matching the away and home team abbreviations.
officials.home_team_idinteger10-digit team id of the home team.
officials.home_team_abbrcharacterThree-letter abbreviation of the home team.
officials.away_team_idinteger10-digit team id of the away team.
officials.away_team_abbrcharacterThree-letter abbreviation of the away team.
officials.crew_positionintegerFeed's official slot order (1-4); slot 1 is inferred to be the crew chief since the API does not label roles.
officials.official_idintegerNumeric official id from the feed (source field official{n}_code); expected to match stats.nba.com's OFFICIAL_ID.
officials.official_namecharacterOfficial's display name for this crew slot.
officials.jersey_numcharacterOfficial's jersey number as a string, from the feed's official{n}_JNum field.
replay_center.leaguecharacterLeague the replay-center staffing belongs to: nba, gl, or wnba.
replay_center.game_datedateDate the replay-center official worked; a date-level staffing record, not tied to one game.
replay_center.official_idintegerNumeric replay-center official id from the feed.
replay_center.official_namecharacterReplay-center official's display name for that date.

Example

from sportsdataverse.wnba.wnba_officiating import wnba_referee_assignments
result = wnba_referee_assignments("2026-06-13")
officials = result["officials"]
print(f"Found {officials.height} official slots")

wnba_shot_value​

wnba_shot_value(player_ids: "'list[int]'", season: 'str', *, include_context: 'bool' = False, return_as_pandas: 'bool' = False) -> "'dict[str, Union[pl.DataFrame, pd.DataFrame]]'"

WNBA one-call shot-value spine (league_id="10").

Thin wrapper binding sportsdataverse.nba.nba_shot_value.nba_shot_value to the women's league; fetches each player's shotchartdetail, scores per-shot expected points from the free LeagueAverages zone table, and returns the scored shots plus shooter talent, selection quality, and zone-value maps (and the defender/shot-clock context tables when include_context=True). Women's court geometry + shrinkage constant are keyed "10" in nba_shot_value_constants.

Parameters

ParameterTypeDefaultDescription
player_idslist[int]Player ids to fetch.
seasonstrSeason string, e.g. "2024".
include_contextboolFalseAlso fetch + return the playerdashptshots defender/shot-clock context tables.
return_as_pandasboolFalseReturn pandas frames instead of polars.

Returns

{"shots", "talent", "selection", "zones"} (plus "context" when requested). An empty fetch returns a dict of zero-row frames.

Example

from sportsdataverse.wnba import wnba_shot_value
out = wnba_shot_value([1628886], "2024")
out["talent"].head()

wnba_team_clutch​

wnba_team_clutch(season: 'int', *, league_id: 'str' = '00', return_as_pandas: 'bool' = False) -> 'Union[pl.DataFrame, pd.DataFrame]'

WNBA clutch skill (league_id='10'). See sportsdataverse.nba.nba_clutch.nba_team_clutch.

Parameters

ParameterTypeDefaultDescription
seasonint
league_idstr'00'
return_as_pandasboolFalse

Returns

One row per team: season, team_id, clutch_net_rating, adj_net_rtg, clutch_delta, clutch_skill_shrunk, clutch_poss. Empty input returns that schema with zero rows.

No returns table is published for this function: no capture: it reads stats.wnba.com, which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

wnba_tracking_drive_value​

wnba_tracking_drive_value(seasons: "'int | str | list'", *, league_id: 'str' = '10', per_mode: 'str' = 'Totals', by_position: 'bool' = True, positions: 'Optional[pl.DataFrame]' = None, return_as_pandas: 'bool' = False, _get_fn: 'Optional[Callable[..., dict]]' = None) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA drive value + rim-pressure (league_id="10" by-reference shim).

See sportsdataverse.nba.nba_tracking_value.nba_tracking_drive_value for the full recipe.

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season or list of seasons.
league_idstr'10'Defaults to "10" (WNBA); pass "20" here for G-League.
per_modestr'Totals'per_mode_simple passed to the fetch (default "Totals").
by_positionboolTrueCompute the baseline within role buckets (default); False forces one league-wide bucket.
positionsOptional[DataFrame]NoneOptional pre-fetched positions frame.
return_as_pandasboolFalseReturn a pandas.DataFrame instead of polars.
_get_fnOptional[Callable[..., dict]]NoneInjectable replacement for nba_stats_leaguedashptstats.

Returns

One row per player-season: season:Int64, player_id:Utf8, player_name:Utf8, team_id:Utf8, position_bucket:Utf8, gp:Int64, min:Float64, drives:Float64, drive_pts:Float64, drive_baseline_rate:Float64, drive_expected:Float64, drive_pts_oe:Float64, drive_pts_oe_per_36:Float64, drive_fta:Float64, rim_pressure:Float64, drive_ast:Float64, drive_tov:Float64, league_id:Utf8. Empty/malformed input returns a zero-row frame with this schema.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_tracking_drive_value
df = wnba_tracking_drive_value(2024)
print(df.sort("drive_pts_oe", descending=True).head())

wnba_tracking_pass_value​

wnba_tracking_pass_value(seasons: "'int | str | list'", *, league_id: 'str' = '10', per_mode: 'str' = 'Totals', by_position: 'bool' = True, positions: 'Optional[pl.DataFrame]' = None, fetch_potential_assists: 'bool' = False, max_players: 'int' = 0, return_as_pandas: 'bool' = False, _get_fn: 'Optional[Callable[..., dict]]' = None, _pass_get_fn: 'Optional[Callable[..., dict]]' = None) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA expected-assists / passer value (league_id="10" by-reference shim).

See sportsdataverse.nba.nba_tracking_value.nba_tracking_pass_value for the full recipe (Passing-measure proxy + optional playerdashptpass enrichment).

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season or list of seasons.
league_idstr'10'Defaults to "10" (WNBA); pass "20" here for G-League.
per_modestr'Totals'per_mode_simple passed to the fetch (default "Totals").
by_positionboolTrueCompute the baseline within role buckets (default); False forces one league-wide bucket.
positionsOptional[DataFrame]NoneOptional pre-fetched positions frame.
fetch_potential_assistsboolFalseEnrich the top passers with playerdashptpass potential-assist counts.
max_playersint0Cap on per-player enrichment fetches; 0 disables enrichment regardless of fetch_potential_assists.
return_as_pandasboolFalseReturn a pandas.DataFrame instead of polars.
_get_fnOptional[Callable[..., dict]]NoneInjectable replacement for nba_stats_leaguedashptstats.
_pass_get_fnOptional[Callable[..., dict]]NoneInjectable replacement for nba_stats_playerdashptpass.

Returns

One row per player-season: season:Int64, player_id:Utf8, player_name:Utf8, team_id:Utf8, position_bucket:Utf8, gp:Int64, min:Float64, ast:Float64, passes:Float64, ast_baseline_rate:Float64, ast_expected:Float64, ast_oe:Float64, ast_oe_per_36:Float64, ast_pts_created:Float64, league_id:Utf8. Empty/malformed input returns a zero-row frame with this schema.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_tracking_pass_value
df = wnba_tracking_pass_value(2024)
print(df.sort("ast_oe", descending=True).head())

wnba_tracking_reb_oe​

wnba_tracking_reb_oe(seasons: "'int | str | list'", *, league_id: 'str' = '10', per_mode: 'str' = 'Totals', by_position: 'bool' = True, positions: 'Optional[pl.DataFrame]' = None, return_as_pandas: 'bool' = False, _get_fn: 'Optional[Callable[..., dict]]' = None) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA rebounding-over-expected (league_id="10" by-reference shim).

See sportsdataverse.nba.nba_tracking_value.nba_tracking_reb_oe for the full recipe (contest-difficulty-adjusted expected rebounds, role-bucket baseline).

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season or list of seasons.
league_idstr'10'Defaults to "10" (WNBA); pass "20" here for G-League.
per_modestr'Totals'per_mode_simple passed to the fetch (default "Totals").
by_positionboolTrueCompute the baseline within role buckets (default); False forces one league-wide bucket.
positionsOptional[DataFrame]NoneOptional pre-fetched positions frame.
return_as_pandasboolFalseReturn a pandas.DataFrame instead of polars.
_get_fnOptional[Callable[..., dict]]NoneInjectable replacement for nba_stats_leaguedashptstats.

Returns

One row per player-season: season:Int64, player_id:Utf8, player_name:Utf8, team_id:Utf8, position_bucket:Utf8, gp:Int64, min:Float64, reb:Float64, reb_chances:Float64, reb_baseline_rate:Float64, reb_expected:Float64, reb_oe:Float64, reb_oe_per_36:Float64, oreb_oe:Float64, dreb_oe:Float64, league_id:Utf8. Empty/malformed input returns a zero-row frame with this schema.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_tracking_reb_oe
df = wnba_tracking_reb_oe(2024)
print(df.sort("reb_oe", descending=True).head())

wnba_tracking_rim_protect_value​

wnba_tracking_rim_protect_value(seasons: "'int | str | list'", *, league_id: 'str' = '10', per_mode: 'str' = 'Totals', by_position: 'bool' = True, positions: 'Optional[pl.DataFrame]' = None, source: 'str' = 'leaguedash', max_players: 'int' = 0, return_as_pandas: 'bool' = False, _get_fn: 'Optional[Callable[..., dict]]' = None, _defend_get_fn: 'Optional[Callable[..., dict]]' = None) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA rim-protection / shot-defend points-saved (league_id="10"

by-reference shim).

See sportsdataverse.nba.nba_tracking_value.nba_tracking_rim_protect_value for the full recipe (bucket-mean defended-rate baseline; optional playerdashptshotdefend rim-band enrichment).

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season or list of seasons.
league_idstr'10'Defaults to "10" (WNBA); pass "20" here for G-League.
per_modestr'Totals'per_mode_simple passed to the fetch (default "Totals").
by_positionboolTrueCompute the baseline within role buckets (default); False forces one league-wide bucket.
positionsOptional[DataFrame]NoneOptional pre-fetched positions frame.
sourcestr'leaguedash'"leaguedash" (default) or "shotdefend".
max_playersint0Cap on per-player shotdefend enrichment fetches; ignored unless source="shotdefend".
return_as_pandasboolFalseReturn a pandas.DataFrame instead of polars.
_get_fnOptional[Callable[..., dict]]NoneInjectable replacement for nba_stats_leaguedashptstats.
_defend_get_fnOptional[Callable[..., dict]]NoneInjectable replacement for nba_stats_playerdashptshotdefend.

Returns

One row per player-season: season:Int64, player_id:Utf8, player_name:Utf8, team_id:Utf8, position_bucket:Utf8, gp:Int64, min:Float64, d_fga:Float64, d_fgm:Float64, d_fg_pct:Float64, normal_fg_pct:Float64, rim_protect_pts_saved:Float64, rim_protect_pts_saved_per_36:Float64, source:Utf8, league_id:Utf8. Empty/malformed input returns a zero-row frame with this schema.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_tracking_rim_protect_value
df = wnba_tracking_rim_protect_value(2024)
print(df.sort("rim_protect_pts_saved", descending=True).head())

wnba_tracking_shot_diet_value​

wnba_tracking_shot_diet_value(seasons: "'int | str | list'", *, league_id: 'str' = '10', per_mode: 'str' = 'Totals', by_position: 'bool' = True, positions: 'Optional[pl.DataFrame]' = None, return_as_pandas: 'bool' = False, _get_fn: 'Optional[Callable[..., dict]]' = None) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA catch-&-shoot vs pull-up points-over-expected (league_id="10"

by-reference shim).

See sportsdataverse.nba.nba_tracking_value.nba_tracking_shot_diet_value for the full recipe.

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season or list of seasons.
league_idstr'10'Defaults to "10" (WNBA); pass "20" here for G-League.
per_modestr'Totals'per_mode_simple passed to each fetch (default "Totals").
by_positionboolTrueCompute each measure's baseline within role buckets (default); False forces one league-wide bucket.
positionsOptional[DataFrame]NoneOptional pre-fetched positions frame.
return_as_pandasboolFalseReturn a pandas.DataFrame instead of polars.
_get_fnOptional[Callable[..., dict]]NoneInjectable replacement for nba_stats_leaguedashptstats.

Returns

One row per player-season: season:Int64, player_id:Utf8, player_name:Utf8, team_id:Utf8, position_bucket:Utf8, cs_fga:Float64, cs_pts:Float64, cs_pts_oe:Float64, pu_fga:Float64, pu_pts:Float64, pu_pts_oe:Float64, shot_diet_delta:Float64, league_id:Utf8. Empty/malformed input returns a zero-row frame with this schema.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_tracking_shot_diet_value
df = wnba_tracking_shot_diet_value(2024)
print(df.sort("cs_pts_oe", descending=True).head())

wnba_tracking_touch_value​

wnba_tracking_touch_value(seasons: "'int | str | list'", *, league_id: 'str' = '10', per_mode: 'str' = 'Totals', by_position: 'bool' = True, positions: 'Optional[pl.DataFrame]' = None, return_as_pandas: 'bool' = False, _get_fn: 'Optional[Callable[..., dict]]' = None) -> "'Union[pl.DataFrame, pd.DataFrame]'"

WNBA touch / possession-time value (league_id="10" by-reference shim).

See sportsdataverse.nba.nba_tracking_value.nba_tracking_touch_value for the full recipe.

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season or list of seasons.
league_idstr'10'Defaults to "10" (WNBA); pass "20" here for G-League.
per_modestr'Totals'per_mode_simple passed to the fetch (default "Totals").
by_positionboolTrueCompute the baseline within role buckets (default); False forces one league-wide bucket.
positionsOptional[DataFrame]NoneOptional pre-fetched positions frame.
return_as_pandasboolFalseReturn a pandas.DataFrame instead of polars.
_get_fnOptional[Callable[..., dict]]NoneInjectable replacement for nba_stats_leaguedashptstats.

Returns

One row per player-season: season:Int64, player_id:Utf8, player_name:Utf8, team_id:Utf8, position_bucket:Utf8, gp:Int64, min:Float64, touches:Float64, pts:Float64, touch_baseline_rate:Float64, touch_expected:Float64, pts_per_touch_oe:Float64, time_of_poss:Float64, time_of_poss_eff:Float64, league_id:Utf8. Empty/malformed input returns a zero-row frame with this schema.

No returns table is published for this function: no capture: it reads stats.nba.com (WNBA league id 10), which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

from sportsdataverse.wnba import wnba_tracking_touch_value
df = wnba_tracking_touch_value(2024)
print(df.sort("pts_per_touch_oe", descending=True).head())

zone_value_map​

zone_value_map(scored_shots: 'pl.DataFrame', *, return_as_pandas: 'bool' = False) -> "'Union[pl.DataFrame, pd.DataFrame]'"

Per-player per-zone value map: points and expected points per shot.

Collapses shot_zone_basic to a canonical zone via ZONE_COLLAPSE (the two corner-3 zones merge) and aggregates realized vs expected points per shot in each zone.

Parameters

ParameterTypeDefaultDescription
scored_shotsDataFramescore_shot_xpoints output (needs player_id, shot_zone_basic, shot_made_flag, actual_points, xpoints).
return_as_pandasboolFalseReturn a pandas DataFrame instead of polars.

Returns

One row per (player_id, zone): player_id:Int64, zone:Utf8, att:Int64, makes:Int64, pts:Float64, pps:Float64, xpps:Float64, pps_above_expected:Float64 (pps = points per shot, xpps = expected). Empty input returns the zero-row schema.

No returns table is published for this function: no capture: its input is the shots frame of wnba_shot_value, which reads stats.nba.com shotchartdetail; that host answers HTTP 403 to the datacenter IP the docs are built on.

Example

from sportsdataverse.nba.nba_shot_value import score_shot_xpoints, zone_value_map
zmap = zone_value_map(score_shot_xpoints(shots, league_avgs))

# Pipeline next step (one line)

zmap.filter(pl.col("zone") == "corner_3").sort("pps_above_expected", descending=True)