Skip to main content

NBA — additional Python functions — Analytics: nba_team–nba_tracking

nba_team_season_rates​

nba_team_season_rates(seasons: 'int | list[int]', *, league_id: 'str' = '00', season_type: 'str' = 'regular-season', return_as_pandas: 'bool' = False) -> 'pl.DataFrame | pd.DataFrame'

Season team rates from possessions: ORtg/DRtg/net, pace and the four factors, with splits.

One row per team, season and split (all, home, away, close, clutch). Clutch is a possession in play with 5:00 or less left (starting there, or starting before 5:00 and ending after it; one that ends at exactly 5:00 is out) in the 4th quarter or an overtime, the score within 5 as it starts (stats.nba.com's clutch window); a close game is one with a clutch possession. For the WNBA (league_id="10") through 2005, two 20-minute halves, the regulation window is the last 5:00 of the 2nd half; overtime counts as above. The full definitions are in sportsdataverse._common.team_season_rates.

Parameters

ParameterTypeDefaultDescription
seasonsint | list[int]A season or list of seasons, named by the year it ends (2026 is 2025-26). The WNBA season is its calendar year.
league_idstr'00'"00" NBA or "10" WNBA.
season_typestr'regular-season'"regular-season" (default), "preseason", "playoffs" or "play-in", matched to the schedule's season_type.
return_as_pandasboolFalseReturn a pandas frame instead of polars.

Returns

One row per (season, team_id, split). team_id is the stats.nba.com team id (Int64). games, poss / opp_poss (offensive / defensive possessions) and pts / opp_pts are the split's totals. The twelve rates are off_rtg, def_rtg, net_rtg (per 100 possessions), pace (possessions per 48 minutes, 40 in the WNBA), the four factors efg_pct, tov_pct, orb_pct, ft_rate and the same four against (opp_*), all fractions. Each rate has <m>_rank (1 = best; def_rtg, tov_pct, opp_efg_pct, opp_orb_pct and opp_ft_rate rank low first; pace ranks high first), <m>_pct (the Weibull percentile) and <m>_n (the sample: possessions for the ratings, the clock in regulation games for pace, field-goal attempts for eFG% and FT rate, possessions for turnover rate, rebound chances for ORB%). Ranks are within the season and split, among teams with at least half the most games whose <m>_n reaches the league's ~sportsdataverse._common.rate_gates.TEAM_MIN_N gate (a clutch split reaches none), and null under five teams. Empty input returns that schema with zero rows.

col_nametypedescription
seasonInt64Season, named by the year it ends (2026 is 2025-26).
team_idInt64stats.nba.com team id (the 10-digit franchise id).
splitStringWhich possessions the row covers: all; home or away (the team's home or road games; neutral-site games are in neither: the curated nba_neutral_site_games list, plus every game dated inside the 2020 bubble (from the schedule's game_date)); close (every possession of a game that had a clutch possession); clutch (a possession in play with 5:00 or less left (starting there, or starting before 5:00 and ending after it) in the 4th quarter (the 2nd half for league_id='10' through 2005, when the WNBA played two 20-minute halves) or an overtime, the score within 5 as it starts).
gamesInt64Games with at least one possession in the split.
possInt64Offensive possessions in the split, counted from possession rows.
opp_possInt64Defensive possessions in the split (the opponents' offensive possessions).
ptsInt64Points scored on the team's offensive possessions in the split. Counted from each possession's made shots and free throws.
opp_ptsInt64Points allowed on the team's defensive possessions in the split.
off_rtgFloat64Offensive rating: points scored per 100 offensive possessions.
def_rtgFloat64Defensive rating: points allowed per 100 defensive possessions.
net_rtgFloat64Net rating: off_rtg minus def_rtg.
paceFloat64Pace: possessions per 48 minutes (40 with league_id="10", the WNBA), the mean of poss and opp_poss over the game clock those possessions used.
efg_pctFloat64Effective field-goal percentage, (FGM + 0.5 * 3PM) / FGA, as a fraction.
tov_pctFloat64Turnovers per offensive possession, as a fraction.
orb_pctFloat64Offensive rebound rate: offensive rebounds over offensive-rebound chances (own OREB plus the defense's DREB), as a fraction.
ft_rateFloat64Free-throw rate, FTA / FGA.
opp_efg_pctFloat64Opponents' effective field-goal percentage, (FGM + 0.5 * 3PM) / FGA, as a fraction.
opp_tov_pctFloat64Opponents' turnovers per possession (turnovers forced), as a fraction.
opp_orb_pctFloat64Opponents' offensive rebound rate, as a fraction (one minus the team's defensive rebound rate).
opp_ft_rateFloat64Opponents' free-throw rate, FTA / FGA.
off_rtg_rankFloat64Rank of off_rtg within the season and split (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose off_rtg_n is at least 1,300 offensive possessions (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
def_rtg_rankFloat64Rank of def_rtg within the season and split (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose def_rtg_n is at least 2,000 defensive possessions (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
net_rtg_rankFloat64Rank of net_rtg within the season and split (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose net_rtg_n is at least 2,000 possessions (offense plus defense) (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
pace_rankFloat64Rank of pace within the season and split (the highest value ranks 1; pace has no better direction; ties average), among teams that played at least half the most games any team played in the split, whose pace_n is at least 5 games (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
efg_pct_rankFloat64Rank of efg_pct within the season and split (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose efg_pct_n is at least 1,200 field-goal attempts (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
tov_pct_rankFloat64Rank of tov_pct within the season and split (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose tov_pct_n is at least 1,400 offensive possessions (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
orb_pct_rankFloat64Rank of orb_pct within the season and split (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose orb_pct_n is at least 410 offensive-rebound chances (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
ft_rate_rankFloat64Rank of ft_rate within the season and split (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose ft_rate_n is at least 1,300 field-goal attempts (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
opp_efg_pct_rankFloat64Rank of opp_efg_pct within the season and split (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose opp_efg_pct_n is at least 1,900 opponent field-goal attempts (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
opp_tov_pct_rankFloat64Rank of opp_tov_pct within the season and split (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose opp_tov_pct_n is at least 960 defensive possessions (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
opp_orb_pct_rankFloat64Rank of opp_orb_pct within the season and split (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose opp_orb_pct_n is at least 1,200 opponent offensive-rebound chances (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
opp_ft_rate_rankFloat64Rank of opp_ft_rate within the season and split (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the split, whose opp_ft_rate_n is at least 1,500 opponent field-goal attempts (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
off_rtg_pctFloat64Percentile of off_rtg within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
def_rtg_pctFloat64Percentile of def_rtg within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
net_rtg_pctFloat64Percentile of net_rtg within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
pace_pctFloat64Percentile of pace within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
efg_pct_pctFloat64Percentile of efg_pct within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
tov_pct_pctFloat64Percentile of tov_pct within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
orb_pct_pctFloat64Percentile of orb_pct within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
ft_rate_pctFloat64Percentile of ft_rate within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
opp_efg_pct_pctFloat64Percentile of opp_efg_pct within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
opp_tov_pct_pctFloat64Percentile of opp_tov_pct within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
opp_orb_pct_pctFloat64Percentile of opp_orb_pct within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
opp_ft_rate_pctFloat64Percentile of opp_ft_rate within the season and split among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
off_rtg_nInt64Sample size of off_rtg: the team's offensive possessions in the split.
def_rtg_nInt64Sample size of def_rtg: the team's defensive possessions in the split.
net_rtg_nInt64Sample size of net_rtg: the team's offensive plus defensive possessions in the split.
pace_nInt64Sample size of pace: the game clock the split's possessions used, in regulation games (48 minutes, 40 in the WNBA and college), rounded: a full game counts 1, a clutch split's five-minute windows about 0.1 each.
efg_pct_nInt64Sample size of efg_pct: the team's field-goal attempts in the split.
tov_pct_nInt64Sample size of tov_pct: the team's offensive possessions in the split.
orb_pct_nInt64Sample size of orb_pct: the team's offensive-rebound chances in the split.
ft_rate_nInt64Sample size of ft_rate: the team's field-goal attempts in the split.
opp_efg_pct_nInt64Sample size of opp_efg_pct: the opponents' field-goal attempts in the split.
opp_tov_pct_nInt64Sample size of opp_tov_pct: the team's defensive possessions in the split.
opp_orb_pct_nInt64Sample size of opp_orb_pct: the opponents' offensive-rebound chances in the split.
opp_ft_rate_nInt64Sample size of opp_ft_rate: the opponents' field-goal attempts in the split.

Raises

ExceptionDescription
ValueErrorIf league_id is not "00" or "10", or season_type is not one of the four above.

Example

from sportsdataverse.nba.nba_team_season_rates import nba_team_season_rates
rates = nba_team_season_rates(2026)
rates.filter(split="all").sort("net_rtg_rank").head()

# WNBA via ``league_id``

wnba = nba_team_season_rates(2025, league_id="10")

nba_team_shot_zones​

nba_team_shot_zones(seasons: 'int | list[int]', *, league_id: 'str' = '00', return_as_pandas: 'bool' = False) -> 'pl.DataFrame | pd.DataFrame'

Season shot profile by zone per team, for and allowed: rim / mid / corner 3 / above-the-break 3.

One row per team and season over the regular season: the team's own attempts and, with an opp_ prefix, its opponents' attempts against it.

Parameters

ParameterTypeDefaultDescription
seasonsint | list[int]A season or list of seasons, named by the year it ends (2026 is 2025-26). The WNBA season is its calendar year.
league_idstr'00'"00" NBA or "10" WNBA.
return_as_pandasboolFalseReturn a pandas frame instead of polars.

Returns

One row per (season, team_id) (the stats.nba.com team id, Int64) with games and the columns of nba_player_shot_zones for the team and again with an opp_ prefix for its opponents (opp_fga, opp_rim_fg_pct, ...), each rate with <m>_n, <m>_rank and <m>_pct, ranked within the season among teams whose <m>_n reaches the gate and null under five teams. <m>_rank is 1 = highest, except the allowed opp_{z}_fg_pct, where 1 is the lowest (the stingiest defense). Empty input returns that schema with zero rows.

col_nametypedescription
seasonInt64Season, named by the year it ends (2026 is 2025-26).
team_idInt64stats.nba.com team id.
gamesInt64The team's regular-season games with a field-goal attempt by or against it.
fgaInt64Field-goal attempts by the team (regular-season games).
fgmInt64Field goals made by the team.
unlocated_fgaInt64Attempts by the team with no real location (the WNBA's 1997-2010 hoop-centre placeholders; 0 elsewhere): counted in fga, in no zone.
rim_fgaInt64Attempts by the team at the rim (the restricted area: shot_distance under 4 ft).
rim_fgmInt64Makes by the team at the rim (the restricted area: shot_distance under 4 ft).
rim_astInt64Assisted makes by the team at the rim (the restricted area: shot_distance under 4 ft).
mid_fgaInt64Attempts by the team in the mid zone (every other two: the paint outside the restricted area and the mid-range).
mid_fgmInt64Makes by the team in the mid zone (every other two: the paint outside the restricted area and the mid-range).
mid_astInt64Assisted makes by the team in the mid zone (every other two: the paint outside the restricted area and the mid-range).
corner_3_fgaInt64Attempts by the team from the corner (a three from the baseline band, y_legacy <= 87.5, below the break).
corner_3_fgmInt64Makes by the team from the corner (a three from the baseline band, y_legacy <= 87.5, below the break).
corner_3_astInt64Assisted makes by the team from the corner (a three from the baseline band, y_legacy <= 87.5, below the break).
above_break_3_fgaInt64Attempts by the team from above the break (every other three).
above_break_3_fgmInt64Makes by the team from above the break (every other three).
above_break_3_astInt64Assisted makes by the team from above the break (every other three).
opp_fgaInt64Allowed: Field-goal attempts by the team's opponents (regular-season games).
opp_fgmInt64Allowed: Field goals made by the team's opponents.
opp_unlocated_fgaInt64Allowed: Attempts by the team's opponents with no real location (the WNBA's 1997-2010 hoop-centre placeholders; 0 elsewhere): counted in opp_fga, in no zone.
opp_rim_fgaInt64Allowed: Attempts by the team's opponents at the rim (the restricted area: shot_distance under 4 ft).
opp_rim_fgmInt64Allowed: Makes by the team's opponents at the rim (the restricted area: shot_distance under 4 ft).
opp_rim_astInt64Allowed: Assisted makes by the team's opponents at the rim (the restricted area: shot_distance under 4 ft).
opp_mid_fgaInt64Allowed: Attempts by the team's opponents in the mid zone (every other two: the paint outside the restricted area and the mid-range).
opp_mid_fgmInt64Allowed: Makes by the team's opponents in the mid zone (every other two: the paint outside the restricted area and the mid-range).
opp_mid_astInt64Allowed: Assisted makes by the team's opponents in the mid zone (every other two: the paint outside the restricted area and the mid-range).
opp_corner_3_fgaInt64Allowed: Attempts by the team's opponents from the corner (a three from the baseline band, y_legacy <= 87.5, below the break).
opp_corner_3_fgmInt64Allowed: Makes by the team's opponents from the corner (a three from the baseline band, y_legacy <= 87.5, below the break).
opp_corner_3_astInt64Allowed: Assisted makes by the team's opponents from the corner (a three from the baseline band, y_legacy <= 87.5, below the break).
opp_above_break_3_fgaInt64Allowed: Attempts by the team's opponents from above the break (every other three).
opp_above_break_3_fgmInt64Allowed: Makes by the team's opponents from above the break (every other three).
opp_above_break_3_astInt64Allowed: Assisted makes by the team's opponents from above the break (every other three).
rim_fg_pctFloat64rim_fgm / rim_fga; null with no attempt.
rim_freqFloat64rim_fga / (fga - unlocated_fga): the zone's share of the located attempts (the four zones add up to 1); null with none.
rim_ast_pctFloat64Share of rim_fgm that were assisted, over the makes (every make's assist is in its description); null with none.
mid_fg_pctFloat64mid_fgm / mid_fga; null with no attempt.
mid_freqFloat64mid_fga / (fga - unlocated_fga): the zone's share of the located attempts (the four zones add up to 1); null with none.
mid_ast_pctFloat64Share of mid_fgm that were assisted, over the makes (every make's assist is in its description); null with none.
corner_3_fg_pctFloat64corner_3_fgm / corner_3_fga; null with no attempt.
corner_3_freqFloat64corner_3_fga / (fga - unlocated_fga): the zone's share of the located attempts (the four zones add up to 1); null with none.
corner_3_ast_pctFloat64Share of corner_3_fgm that were assisted, over the makes (every make's assist is in its description); null with none.
above_break_3_fg_pctFloat64above_break_3_fgm / above_break_3_fga; null with no attempt.
above_break_3_freqFloat64above_break_3_fga / (fga - unlocated_fga): the zone's share of the located attempts (the four zones add up to 1); null with none.
above_break_3_ast_pctFloat64Share of above_break_3_fgm that were assisted, over the makes (every make's assist is in its description); null with none.
opp_rim_fg_pctFloat64Allowed: opp_rim_fgm / opp_rim_fga; null with no attempt.
opp_rim_freqFloat64Allowed: opp_rim_fga / (opp_fga - opp_unlocated_fga): the zone's share of the located attempts (the four zones add up to 1); null with none.
opp_rim_ast_pctFloat64Allowed: Share of opp_rim_fgm that were assisted, over the makes (every make's assist is in its description); null with none.
opp_mid_fg_pctFloat64Allowed: opp_mid_fgm / opp_mid_fga; null with no attempt.
opp_mid_freqFloat64Allowed: opp_mid_fga / (opp_fga - opp_unlocated_fga): the zone's share of the located attempts (the four zones add up to 1); null with none.
opp_mid_ast_pctFloat64Allowed: Share of opp_mid_fgm that were assisted, over the makes (every make's assist is in its description); null with none.
opp_corner_3_fg_pctFloat64Allowed: opp_corner_3_fgm / opp_corner_3_fga; null with no attempt.
opp_corner_3_freqFloat64Allowed: opp_corner_3_fga / (opp_fga - opp_unlocated_fga): the zone's share of the located attempts (the four zones add up to 1); null with none.
opp_corner_3_ast_pctFloat64Allowed: Share of opp_corner_3_fgm that were assisted, over the makes (every make's assist is in its description); null with none.
opp_above_break_3_fg_pctFloat64Allowed: opp_above_break_3_fgm / opp_above_break_3_fga; null with no attempt.
opp_above_break_3_freqFloat64Allowed: opp_above_break_3_fga / (opp_fga - opp_unlocated_fga): the zone's share of the located attempts (the four zones add up to 1); null with none.
opp_above_break_3_ast_pctFloat64Allowed: Share of opp_above_break_3_fgm that were assisted, over the makes (every make's assist is in its description); null with none.
rim_fg_pct_nInt64Sample size of rim_fg_pct: rim_fga.
rim_freq_nInt64Sample size of rim_freq: located attempts (fga - unlocated_fga).
rim_ast_pct_nInt64Sample size of rim_ast_pct: makes in the zone.
mid_fg_pct_nInt64Sample size of mid_fg_pct: mid_fga.
mid_freq_nInt64Sample size of mid_freq: located attempts (fga - unlocated_fga).
mid_ast_pct_nInt64Sample size of mid_ast_pct: makes in the zone.
corner_3_fg_pct_nInt64Sample size of corner_3_fg_pct: corner_3_fga.
corner_3_freq_nInt64Sample size of corner_3_freq: located attempts (fga - unlocated_fga).
corner_3_ast_pct_nInt64Sample size of corner_3_ast_pct: makes in the zone.
above_break_3_fg_pct_nInt64Sample size of above_break_3_fg_pct: above_break_3_fga.
above_break_3_freq_nInt64Sample size of above_break_3_freq: located attempts (fga - unlocated_fga).
above_break_3_ast_pct_nInt64Sample size of above_break_3_ast_pct: makes in the zone.
opp_rim_fg_pct_nInt64Sample size of opp_rim_fg_pct: opp_rim_fga.
opp_rim_freq_nInt64Sample size of opp_rim_freq: located attempts (opp_fga - opp_unlocated_fga).
opp_rim_ast_pct_nInt64Sample size of opp_rim_ast_pct: makes in the zone.
opp_mid_fg_pct_nInt64Sample size of opp_mid_fg_pct: opp_mid_fga.
opp_mid_freq_nInt64Sample size of opp_mid_freq: located attempts (opp_fga - opp_unlocated_fga).
opp_mid_ast_pct_nInt64Sample size of opp_mid_ast_pct: makes in the zone.
opp_corner_3_fg_pct_nInt64Sample size of opp_corner_3_fg_pct: opp_corner_3_fga.
opp_corner_3_freq_nInt64Sample size of opp_corner_3_freq: located attempts (opp_fga - opp_unlocated_fga).
opp_corner_3_ast_pct_nInt64Sample size of opp_corner_3_ast_pct: makes in the zone.
opp_above_break_3_fg_pct_nInt64Sample size of opp_above_break_3_fg_pct: opp_above_break_3_fga.
opp_above_break_3_freq_nInt64Sample size of opp_above_break_3_freq: located attempts (opp_fga - opp_unlocated_fga).
opp_above_break_3_ast_pct_nInt64Sample size of opp_above_break_3_ast_pct: makes in the zone.
rim_fg_pct_rankFloat64Rank of rim_fg_pct within the season (the highest ranks 1; ties average), among teams whose rim_fg_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
rim_freq_rankFloat64Rank of rim_freq within the season (the highest ranks 1; ties average), among teams whose rim_freq_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
rim_ast_pct_rankFloat64Rank of rim_ast_pct within the season (the highest ranks 1; ties average), among teams whose rim_ast_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
mid_fg_pct_rankFloat64Rank of mid_fg_pct within the season (the highest ranks 1; ties average), among teams whose mid_fg_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
mid_freq_rankFloat64Rank of mid_freq within the season (the highest ranks 1; ties average), among teams whose mid_freq_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
mid_ast_pct_rankFloat64Rank of mid_ast_pct within the season (the highest ranks 1; ties average), among teams whose mid_ast_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
corner_3_fg_pct_rankFloat64Rank of corner_3_fg_pct within the season (the highest ranks 1; ties average), among teams whose corner_3_fg_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
corner_3_freq_rankFloat64Rank of corner_3_freq within the season (the highest ranks 1; ties average), among teams whose corner_3_freq_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
corner_3_ast_pct_rankFloat64Rank of corner_3_ast_pct within the season (the highest ranks 1; ties average), among teams whose corner_3_ast_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
above_break_3_fg_pct_rankFloat64Rank of above_break_3_fg_pct within the season (the highest ranks 1; ties average), among teams whose above_break_3_fg_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
above_break_3_freq_rankFloat64Rank of above_break_3_freq within the season (the highest ranks 1; ties average), among teams whose above_break_3_freq_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
above_break_3_ast_pct_rankFloat64Rank of above_break_3_ast_pct within the season (the highest ranks 1; ties average), among teams whose above_break_3_ast_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_rim_fg_pct_rankFloat64Rank of opp_rim_fg_pct within the season (the lowest ranks 1, the stingiest defense; ties average), among teams whose opp_rim_fg_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_rim_freq_rankFloat64Rank of opp_rim_freq within the season (the highest ranks 1; ties average), among teams whose opp_rim_freq_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_rim_ast_pct_rankFloat64Rank of opp_rim_ast_pct within the season (the highest ranks 1; ties average), among teams whose opp_rim_ast_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_mid_fg_pct_rankFloat64Rank of opp_mid_fg_pct within the season (the lowest ranks 1, the stingiest defense; ties average), among teams whose opp_mid_fg_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_mid_freq_rankFloat64Rank of opp_mid_freq within the season (the highest ranks 1; ties average), among teams whose opp_mid_freq_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_mid_ast_pct_rankFloat64Rank of opp_mid_ast_pct within the season (the highest ranks 1; ties average), among teams whose opp_mid_ast_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_corner_3_fg_pct_rankFloat64Rank of opp_corner_3_fg_pct within the season (the lowest ranks 1, the stingiest defense; ties average), among teams whose opp_corner_3_fg_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_corner_3_freq_rankFloat64Rank of opp_corner_3_freq within the season (the highest ranks 1; ties average), among teams whose opp_corner_3_freq_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_corner_3_ast_pct_rankFloat64Rank of opp_corner_3_ast_pct within the season (the highest ranks 1; ties average), among teams whose opp_corner_3_ast_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_above_break_3_fg_pct_rankFloat64Rank of opp_above_break_3_fg_pct within the season (the lowest ranks 1, the stingiest defense; ties average), among teams whose opp_above_break_3_fg_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_above_break_3_freq_rankFloat64Rank of opp_above_break_3_freq within the season (the highest ranks 1; ties average), among teams whose opp_above_break_3_freq_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
opp_above_break_3_ast_pct_rankFloat64Rank of opp_above_break_3_ast_pct within the season (the highest ranks 1; ties average), among teams whose opp_above_break_3_ast_pct_n reaches the rate's split-half gate (TEAM_MIN_N); null under the gate, for a rate with no gate (never half signal), or with fewer than five teams ranked.
rim_fg_pct_pctFloat64Percentile of rim_fg_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
rim_freq_pctFloat64Percentile of rim_freq within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
rim_ast_pct_pctFloat64Percentile of rim_ast_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
mid_fg_pct_pctFloat64Percentile of mid_fg_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
mid_freq_pctFloat64Percentile of mid_freq within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
mid_ast_pct_pctFloat64Percentile of mid_ast_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
corner_3_fg_pct_pctFloat64Percentile of corner_3_fg_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
corner_3_freq_pctFloat64Percentile of corner_3_freq within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
corner_3_ast_pct_pctFloat64Percentile of corner_3_ast_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
above_break_3_fg_pct_pctFloat64Percentile of above_break_3_fg_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
above_break_3_freq_pctFloat64Percentile of above_break_3_freq within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
above_break_3_ast_pct_pctFloat64Percentile of above_break_3_ast_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_rim_fg_pct_pctFloat64Percentile of opp_rim_fg_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_rim_freq_pctFloat64Percentile of opp_rim_freq within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_rim_ast_pct_pctFloat64Percentile of opp_rim_ast_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_mid_fg_pct_pctFloat64Percentile of opp_mid_fg_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_mid_freq_pctFloat64Percentile of opp_mid_freq within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_mid_ast_pct_pctFloat64Percentile of opp_mid_ast_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_corner_3_fg_pct_pctFloat64Percentile of opp_corner_3_fg_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_corner_3_freq_pctFloat64Percentile of opp_corner_3_freq within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_corner_3_ast_pct_pctFloat64Percentile of opp_corner_3_ast_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_above_break_3_fg_pct_pctFloat64Percentile of opp_above_break_3_fg_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_above_break_3_freq_pctFloat64Percentile of opp_above_break_3_freq within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.
opp_above_break_3_ast_pct_pctFloat64Percentile of opp_above_break_3_ast_pct within the season among the same ranked rows: 100 * (n + 1 - rank) / (n + 1), n the number ranked; null when the rank is null.

Raises

ExceptionDescription
ValueErrorIf league_id is not "00" or "10" (checked before any data is loaded).

Example

from sportsdataverse.nba.nba_shot_zone_profiles import nba_team_shot_zones
teams = nba_team_shot_zones(2025)
teams.sort("opp_rim_freq").select("team_id", "opp_rim_freq", "opp_rim_fg_pct").head()

# WNBA via ``league_id``

wnba = nba_team_shot_zones(2025, league_id="10")

nba_team_strength​

nba_team_strength(seasons: 'int | list[int]', *, league_id: 'str' = '00', season_type: 'str' = 'regular-season', return_as_pandas: 'bool' = False) -> 'pl.DataFrame | pd.DataFrame'

Team strength from possessions: adjusted ratings, SOS, SOV, pace and the four factors.

One row per team and season. The adjusted ratings are a ridge regression of points per 100 on each possession on offense, defense and home terms (penalty ~sportsdataverse._common.team_strength.RIDGE_LAMBDA, fit by season-disjoint CV): points scored / allowed per 100 against an average opponent on a neutral court. SOS is the mean opponent adj_net_rtg over the team's games, SOV the same over its wins.

Parameters

ParameterTypeDefaultDescription
seasonsint | list[int]A season or list of seasons, named by the year it ends (2026 is 2025-26). The WNBA season is its calendar year.
league_idstr'00'"00" NBA or "10" WNBA.
season_typestr'regular-season'"regular-season" (default), "preseason", "playoffs" or "play-in", matched to the schedule's season_type. The ridge, the rates and the games all use it.
return_as_pandasboolFalseReturn a pandas frame instead of polars.

Returns

One row per (season, team_id); team_id is the stats.nba.com team id (Int64). games, poss / opp_poss, pts / opp_pts are the season totals from the possessions; wins / losses come from the schedule's final scores. The rated metrics are adj_off_rtg, adj_def_rtg, adj_net_rtg, sos, sov and the BB-D3 rates (off_rtg, def_rtg, net_rtg, pace, the four factors and the four against). Each has <m>_rank (1 = best; adj_def_rtg, def_rtg, tov_pct and the opponent shooting, rebounding and free-throw rates rank low first; sos ranks the hardest schedule first), <m>_pct (the Weibull percentile) and <m>_n (possessions for the ratings, completed games against a rated opponent for SOS, the clock in regulation games for pace, wins over a rated opponent for SOV). Ranks are within the season, among teams with at least half the most games, the BB-D3 rates' also behind their ~sportsdataverse._common.rate_gates.TEAM_MIN_N gate, and null under five teams. Empty input returns that schema with zero rows.

col_nametypedescription
seasonInt64Season, named by the year it ends (2026 is 2025-26).
team_idInt64stats.nba.com team id (the 10-digit franchise id).
gamesInt64Games with at least one possession in the season (from the possession release).
winsInt64Wins in the season type's completed games (the schedule's final scores).
lossesInt64Losses in the season type's completed games.
possInt64Offensive possessions in the season, counted from possession rows.
opp_possInt64Defensive possessions in the season (the opponents' offensive possessions).
ptsInt64Points scored on the team's offensive possessions in the season. Counted from each possession's made shots and free throws.
opp_ptsInt64Points allowed on the team's defensive possessions in the season.
adj_off_rtgFloat64Adjusted offensive rating: points per 100 possessions against an average defense on a neutral court. The ridge intercept plus the team's offense coefficient (points per 100 on each possession on offense, defense and home terms; penalty RIDGE_LAMBDA).
adj_def_rtgFloat64Adjusted defensive rating: points allowed per 100 possessions against an average offense on a neutral court. The ridge intercept plus the team's defense coefficient; lower is better.
adj_net_rtgFloat64Adjusted net rating: adj_off_rtg minus adj_def_rtg.
sosFloat64Strength of schedule: the mean adj_net_rtg of the opponents of the team's completed games, one weight per game (an opponent met four times counts four times).
sovFloat64Strength of victory: the mean adj_net_rtg of the opponents the team beat, one weight per win; null with no win.
off_rtgFloat64Offensive rating: points scored per 100 offensive possessions.
def_rtgFloat64Defensive rating: points allowed per 100 defensive possessions.
net_rtgFloat64Net rating: off_rtg minus def_rtg.
paceFloat64Pace: possessions per 48 minutes (40 with league_id="10", the WNBA), the mean of poss and opp_poss over the game clock those possessions used.
efg_pctFloat64Effective field-goal percentage, (FGM + 0.5 * 3PM) / FGA, as a fraction.
tov_pctFloat64Turnovers per offensive possession, as a fraction.
orb_pctFloat64Offensive rebound rate: offensive rebounds over offensive-rebound chances (own OREB plus the defense's DREB), as a fraction.
ft_rateFloat64Free-throw rate, FTA / FGA.
opp_efg_pctFloat64Opponents' effective field-goal percentage, (FGM + 0.5 * 3PM) / FGA, as a fraction.
opp_tov_pctFloat64Opponents' turnovers per possession (turnovers forced), as a fraction.
opp_orb_pctFloat64Opponents' offensive rebound rate, as a fraction (one minus the team's defensive rebound rate).
opp_ft_rateFloat64Opponents' free-throw rate, FTA / FGA.
adj_off_rtg_rankFloat64Rank of adj_off_rtg within the season (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the season; null for a non-qualifier, a null value, or fewer than five qualifiers.
adj_def_rtg_rankFloat64Rank of adj_def_rtg within the season (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the season; null for a non-qualifier, a null value, or fewer than five qualifiers.
adj_net_rtg_rankFloat64Rank of adj_net_rtg within the season (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the season; null for a non-qualifier, a null value, or fewer than five qualifiers.
sos_rankFloat64Rank of sos within the season (the highest value ranks 1; the hardest schedule ranks 1; ties average), among teams that played at least half the most games any team played in the season; null for a non-qualifier, a null value, or fewer than five qualifiers.
sov_rankFloat64Rank of sov within the season (the highest value ranks 1; the strongest wins rank 1; ties average), among teams that played at least half the most games any team played in the season; null for a non-qualifier, a null value, or fewer than five qualifiers.
off_rtg_rankFloat64Rank of off_rtg within the season (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose off_rtg_n is at least 1,300 offensive possessions (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
def_rtg_rankFloat64Rank of def_rtg within the season (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose def_rtg_n is at least 2,000 defensive possessions (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
net_rtg_rankFloat64Rank of net_rtg within the season (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose net_rtg_n is at least 2,000 possessions (offense plus defense) (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
pace_rankFloat64Rank of pace within the season (the highest value ranks 1; pace has no better direction; ties average), among teams that played at least half the most games any team played in the season, whose pace_n is at least 5 games (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
efg_pct_rankFloat64Rank of efg_pct within the season (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose efg_pct_n is at least 1,200 field-goal attempts (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
tov_pct_rankFloat64Rank of tov_pct within the season (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose tov_pct_n is at least 1,400 offensive possessions (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
orb_pct_rankFloat64Rank of orb_pct within the season (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose orb_pct_n is at least 410 offensive-rebound chances (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
ft_rate_rankFloat64Rank of ft_rate within the season (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose ft_rate_n is at least 1,300 field-goal attempts (the sample at which the rate is half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
opp_efg_pct_rankFloat64Rank of opp_efg_pct within the season (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose opp_efg_pct_n is at least 1,900 opponent field-goal attempts (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
opp_tov_pct_rankFloat64Rank of opp_tov_pct within the season (the highest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose opp_tov_pct_n is at least 960 defensive possessions (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
opp_orb_pct_rankFloat64Rank of opp_orb_pct within the season (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose opp_orb_pct_n is at least 1,200 opponent offensive-rebound chances (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
opp_ft_rate_rankFloat64Rank of opp_ft_rate within the season (the lowest value ranks 1; ties average), among teams that played at least half the most games any team played in the season, whose opp_ft_rate_n is at least 1,500 opponent field-goal attempts (the sample at which the rate was, on the fit seasons, half signal, rate_gates); null for a non-qualifier, a sample under that gate, a null rate, or fewer than five qualifiers.
adj_off_rtg_pctFloat64Percentile of adj_off_rtg within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
adj_def_rtg_pctFloat64Percentile of adj_def_rtg within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
adj_net_rtg_pctFloat64Percentile of adj_net_rtg within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
sos_pctFloat64Percentile of sos within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
sov_pctFloat64Percentile of sov within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
off_rtg_pctFloat64Percentile of off_rtg within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
def_rtg_pctFloat64Percentile of def_rtg within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
net_rtg_pctFloat64Percentile of net_rtg within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
pace_pctFloat64Percentile of pace within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
efg_pct_pctFloat64Percentile of efg_pct within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
tov_pct_pctFloat64Percentile of tov_pct within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
orb_pct_pctFloat64Percentile of orb_pct within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
ft_rate_pctFloat64Percentile of ft_rate within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
opp_efg_pct_pctFloat64Percentile of opp_efg_pct within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
opp_tov_pct_pctFloat64Percentile of opp_tov_pct within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
opp_orb_pct_pctFloat64Percentile of opp_orb_pct within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
opp_ft_rate_pctFloat64Percentile of opp_ft_rate within the season among the same qualified teams: 100 * (n + 1 - rank) / (n + 1), n the number ranked, so the best team is under 100 and nobody is 0; null when the rank is null.
adj_off_rtg_nInt64Sample size of adj_off_rtg: the team's offensive possessions in the season.
adj_def_rtg_nInt64Sample size of adj_def_rtg: the team's defensive possessions in the season.
adj_net_rtg_nInt64Sample size of adj_net_rtg: the team's offensive plus defensive possessions in the season.
sos_nInt64Sample size of sos: the completed games against a rated opponent.
sov_nInt64Sample size of sov: the wins against a rated opponent.
off_rtg_nInt64Sample size of off_rtg: the team's offensive possessions in the season.
def_rtg_nInt64Sample size of def_rtg: the team's defensive possessions in the season.
net_rtg_nInt64Sample size of net_rtg: the team's offensive plus defensive possessions in the season.
pace_nInt64Sample size of pace: the game clock the season's possessions used, in regulation games (48 minutes, 40 in the WNBA and college), rounded: about the games played, overtime adding a little.
efg_pct_nInt64Sample size of efg_pct: the team's field-goal attempts in the season.
tov_pct_nInt64Sample size of tov_pct: the team's offensive possessions in the season.
orb_pct_nInt64Sample size of orb_pct: the team's offensive-rebound chances in the season.
ft_rate_nInt64Sample size of ft_rate: the team's field-goal attempts in the season.
opp_efg_pct_nInt64Sample size of opp_efg_pct: the opponents' field-goal attempts in the season.
opp_tov_pct_nInt64Sample size of opp_tov_pct: the team's defensive possessions in the season.
opp_orb_pct_nInt64Sample size of opp_orb_pct: the opponents' offensive-rebound chances in the season.
opp_ft_rate_nInt64Sample size of opp_ft_rate: the opponents' field-goal attempts in the season.

Raises

ExceptionDescription
ValueErrorIf league_id is not "00" or "10", or season_type is not one of the four above (checked before any data is loaded).

Example

from sportsdataverse.nba.nba_team_strength import nba_team_strength
strength = nba_team_strength(2026)
strength.sort("adj_net_rtg_rank").select("team_id", "adj_net_rtg", "sos", "sov").head()

# WNBA via ``league_id``

wnba = nba_team_strength(2025, league_id="10")

nba_tracking_drive_value​

nba_tracking_drive_value(seasons: "'int | str | list'", *, league_id: 'str' = '00', 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]'"

Drive value over expected + rim-pressure, per player-season.

Fetches the Drives leaguedashptstats measure and computes drive_pts_oe = drive_pts - drives * bucket_pts_per_drive. rim_pressure is the z-score of drive_fta / drives within the player's role bucket (a proxy for foul-drawing pressure independent of scoring efficiency). drive_ast/drive_tov are passed through unchanged.

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season or list of seasons.
league_idstr'00'"00" NBA (default), "10" WNBA, "20" 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, which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

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

nba_tracking_pass_value​

nba_tracking_pass_value(seasons: "'int | str | list'", *, league_id: 'str' = '00', 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]'"

Expected-assists / passer value: ast_oe per player-season.

Fetches the Passing leaguedashptstats measure (one call) and computes ast_oe = ast - passes * bucket_assist_rate. When fetch_potential_assists=True, also fetches nba_stats_playerdashptpass for the top-max_players passers (capped, optional -- never a hard dependency) and recomputes the residual against the richer potential_assists denominator for that subset; max_players=0 (default) makes exactly one request total. ast_pts_created is passed through directly from the Passing measure (it is already computed there; not re-derived).

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season or list of seasons.
league_idstr'00'"00" NBA (default), "10" WNBA, "20" 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, which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

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

# With potential-assist enrichment for the top 50 passers

df = nba_tracking_pass_value(2024, fetch_potential_assists=True, max_players=50)

nba_tracking_reb_oe​

nba_tracking_reb_oe(seasons: "'int | str | list'", *, league_id: 'str' = '00', 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]'"

Rebounding-over-expected: reb_oe plus OREB/DREB splits, per player-season.

Fetches the Rebounding leaguedashptstats measure, attaches a guard/wing/big role bucket, and computes reb_oe = reb - reb_chances * bucket_rate (contest-difficulty-adjusted when the endpoint carries separate contested/uncontested CHANCE columns; the live stats.nba.com payload currently does not, so this degrades gracefully to the plain rate -- see the fixtures README for the finding). OREB/DREB residuals are computed identically against their own chance columns. Baselines are recomputed from the same season slice on every call -- there is no fitted constant or bundled artifact.

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season (int ending-year or "YYYY-YY" string) or a list of seasons to concatenate.
league_idstr'00'"00" NBA (default), "10" WNBA, "20" G-League.
per_modestr'Totals'per_mode_simple passed to the fetch (default "Totals").
by_positionboolTrueCompute the baseline within guard/wing/big buckets (default). False forces one league-wide bucket.
positionsOptional[DataFrame]NoneOptional pre-fetched positions frame (see _attach_role_bucket); mostly for injecting a fixture in tests.
return_as_pandasboolFalseReturn a pandas.DataFrame instead of polars.
_get_fnOptional[Callable[..., dict]]NoneInjectable replacement for nba_stats_leaguedashptstats returning the raw payload dict directly -- offline testing hook.

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, which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

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

# League-wide baseline (no position split)

df_all = nba_tracking_reb_oe(2024, by_position=False)

# Pandas output

df_pd = nba_tracking_reb_oe(2024, return_as_pandas=True)

nba_tracking_rim_protect_value​

nba_tracking_rim_protect_value(seasons: "'int | str | list'", *, league_id: 'str' = '00', 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]'"

Rim-protection / shot-defend points-saved over expected, per player-season.

Fetches the Defense leaguedashptstats measure -- which on the live stats.nba.com payload exposes only rim-band defended shooting (def_rim_fgm/def_rim_fga/def_rim_fg_pct, no separate overall figure -- see the fixtures README) -- and computes rim_protect_pts_saved = (normal_fg_pct - d_fg_pct) * d_fga * 2 where normal_fg_pct is the bucket-mean defended rate (there is no shooters'-own-average column on this endpoint, so the bucket mean is the baseline; this is the same attempts-weighted construction as every other model, just sign-flipped so a defender who holds shooters BELOW the bucket mean gets a positive points-saved value).

source="shotdefend" swaps in the Less-Than-6-Ft band from nba_stats_playerdashptshotdefend for the top-max_players defenders by attempt volume (capped, optional -- never a hard dependency); max_players=0 (default) uses the leaguedash figures for everyone.

Parameters

ParameterTypeDefaultDescription
seasonsint | str | listA single season or list of seasons.
league_idstr'00'"00" NBA (default), "10" WNBA, "20" 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, which answers HTTP 403 to the datacenter IP the docs are built on; the function works from a residential IP.

Example

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