Skip to main content
Version: main

๐Ÿˆ The NFL with sportsdataverse-py

Welcome to gridiron data! ๐ŸŽ‰ In a handful of lines you're about to pull standings, rosters, weekly injury reports, NextGen Stats tracking leaderboards, and full play-by-play โ€” straight from the source.

sportsdataverse.nfl leads with the premium api.nfl.com native endpoints (nfl_standings, nfl_rosters, nfl_injuries, โ€ฆ) and the NextGen Stats tracking API (nfl_ngs_*), backed by the battle-tested nflverse release loaders (load_nfl_pbp, load_nfl_player_stats, โ€ฆ). ESPN (espn_nfl_*) rides shotgun as a quick, no-auth secondary path.

Every accessor hands you a tidy polars DataFrame by default โ€” pass return_as_pandas=True for pandas. If you've used the R packages nflfastR / nflreadr, or the Python nflreadpy, you're already home: the load_* names line up. Let's hike it! ๐Ÿˆ

๐Ÿงฐ The toolboxโ€‹

Three data families, one module. The ๐ŸŸข premium rows lead with native api.nfl.com / NextGen Stats endpoints; the ๐Ÿ“ฆ rows read versioned nflverse release parquets; ESPN is the ๐Ÿ”ต quick secondary path. Click any name for the full reference.

FunctionWhat it gives youSource
nfl_standingsTeam standings for a season/week โ€” one row per team๐ŸŸข premium (NFL.com)
nfl_rostersSeason rosters, one row per team (players nested)๐ŸŸข premium (NFL.com)
nfl_injuriesWeekly injury report, one row per player๐ŸŸข premium (NFL.com)
nfl_weeksThe week calendar (bye weeks, date ranges)๐ŸŸข premium (NFL.com)
nfl_weekly_game_detailsRich per-game details for a week (drive charts, standings)๐ŸŸข premium (NFL.com)
nfl_game_summariesLive game state, one row per game๐ŸŸข premium (NFL.com)
nfl_teamSingle-team detail by team_id๐ŸŸข premium (NFL.com)
nfl_ngs_statboardNextGen Stats season leaderboard (passing/rushing/receiving)๐ŸŸข premium (NextGen Stats)
nfl_ngs_leadersNextGen top-N highlight boards (speed, YAC over expected, โ€ฆ)๐ŸŸข premium (NextGen Stats)
nfl_ngs_league_scheduleNextGen schedule โ€” source of NGS gameIds๐ŸŸข premium (NextGen Stats)
nfl_ngs_gamecenter_overviewPer-game NextGen player splits (passers/rushers/โ€ฆ)๐ŸŸข premium (NextGen Stats)
load_nfl_pbpFull nflfastR play-by-play (370+ columns)๐Ÿ“ฆ nflverse release
load_nfl_player_statsWeekly player box-score stats๐Ÿ“ฆ nflverse release
load_nfl_nextgen_statsNextGen Stats back to 2016 (release parquet)๐Ÿ“ฆ nflverse release
load_nfl_rostersSeason rosters with IDs & bios๐Ÿ“ฆ nflverse release
espn_nfl_schedule ยท espn_nfl_scoreboardESPN scoreboard/schedule (no auth)๐Ÿ”ต ESPN (secondary)
load_nfl_snap_countsWeekly snap counts & snap-share % per player๐Ÿ“ฆ nflverse release
load_nfl_depth_chartsWeekly depth charts, one row per slotted player๐Ÿ“ฆ nflverse release
load_nfl_scheduleGame results + lines, one row per game๐Ÿ“ฆ nflverse release
load_nfl_draft_picksEvery draft pick + career value, one row per pick๐Ÿ“ฆ nflverse release
get_current_nfl_season ยท most_recent_nfl_seasonSeason helpers๐ŸŸข helper

๐Ÿ”Œ Setupโ€‹

pip install sportsdataverse

No API key needed โ€” the native api.nfl.com wrappers mint a fresh anonymous token for you, and the NextGen Stats client warms its own browser cookies. The nflverse loaders just read public release parquets. ๐Ÿ˜Š

import polars as pl
import sportsdataverse.nfl as nfl

pl.Config.set_tbl_cols(8) # keep wide frames readable in the notebook

polars.config.Config

Native NFL.com / NextGen endpoints and ESPN are live services โ€” great in-season, occasionally grumpy in the offseason or behind a flaky network. A tiny safe() helper runs each live call defensively: you get the frame when the feed is up, and a friendly one-liner when it isn't (never a scary traceback). ๐Ÿ›Ÿ The load_* release parquets are reliable, so we call those directly.

def safe(label, thunk):
"""Run a live call; return its result, or print a one-liner and return None."""
try:
out = thunk()
print(f"โœ… {label}")
return out
except Exception as e: # noqa: BLE001 -- demo resilience over network blips
print(f"โญ๏ธ {label}: unavailable right now ({type(e).__name__})")
return None


# 2024 is a complete season with full data everywhere โ€” a safe default to demo.
SEASON = 2024

๐ŸŸข Premium first: NFL.com native standingsโ€‹

The headliner. nfl_standings returns one row per team with conference/division records, streaks, clinch flags, point differentials โ€” the works. Pass season, season_type ("REG"/"POST"/"PRE" โ€” strings, not ESPN's numeric codes) and week.

standings = safe(
"NFL.com standings",
lambda: nfl.nfl_standings(season=SEASON, season_type="REG", week=18),
)
standings.shape if standings is not None else "standings unavailable"

โœ… NFL.com standings





(32, 53)
cols = [
"team_full_name", "conference_rank", "division_rank",
"overall_wins", "overall_losses", "overall_ties",
"division_wins", "division_losses",
]
(standings.select([c for c in cols if c in standings.columns])
.sort("conference_rank")
.head(10)
if standings is not None else "standings unavailable")

shape: (10, 8)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ team_full_ โ”† conference โ”† division_r โ”† overall_w โ”† overall_l โ”† overall_t โ”† division_ โ”† division_ โ”‚
โ”‚ name โ”† _rank โ”† ank โ”† ins โ”† osses โ”† ies โ”† wins โ”† losses โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† i64 โ”† i64 โ”† i64 โ”† i64 โ”† i64 โ”† i64 โ”† i64 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Detroit โ”† 1 โ”† 1 โ”† 15 โ”† 2 โ”† 0 โ”† 6 โ”† 0 โ”‚
โ”‚ Lions โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Kansas โ”† 1 โ”† 1 โ”† 15 โ”† 2 โ”† 0 โ”† 5 โ”† 1 โ”‚
โ”‚ City โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Chiefs โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Buffalo โ”† 2 โ”† 1 โ”† 13 โ”† 4 โ”† 0 โ”† 5 โ”† 1 โ”‚
โ”‚ Bills โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Philadelph โ”† 2 โ”† 1 โ”† 14 โ”† 3 โ”† 0 โ”† 5 โ”† 1 โ”‚
โ”‚ ia Eagles โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Baltimore โ”† 3 โ”† 1 โ”† 12 โ”† 5 โ”† 0 โ”† 4 โ”† 2 โ”‚
โ”‚ Ravens โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Tampa Bay โ”† 3 โ”† 1 โ”† 10 โ”† 7 โ”† 0 โ”† 4 โ”† 2 โ”‚
โ”‚ Buccaneers โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Houston โ”† 4 โ”† 1 โ”† 10 โ”† 7 โ”† 0 โ”† 5 โ”† 1 โ”‚
โ”‚ Texans โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Los โ”† 4 โ”† 1 โ”† 10 โ”† 7 โ”† 0 โ”† 4 โ”† 2 โ”‚
โ”‚ Angeles โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Rams โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Los โ”† 5 โ”† 2 โ”† 11 โ”† 6 โ”† 0 โ”† 4 โ”† 2 โ”‚
โ”‚ Angeles โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Chargers โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Minnesota โ”† 5 โ”† 2 โ”† 14 โ”† 3 โ”† 0 โ”† 4 โ”† 2 โ”‚
โ”‚ Vikings โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ‘ฅ Rosters & the week calendarโ€‹

nfl_rosters gives one row per team for a season, with the player list nested under persons (great for a team directory). nfl_weeks is the season's week calendar โ€” handy for finding bye weeks and date ranges before you loop over a slate.

FunctionOne row perKey columns
nfl_rostersteamteam_abbreviation, team_conference_abbr, persons
nfl_weeksweekweek, week_type, bye_teams, date_begin
rosters = safe("NFL.com rosters", lambda: nfl.nfl_rosters(season=SEASON))
cols = ["team_abbreviation", "team_full_name", "team_conference_abbr", "team_division_full_name"]
(rosters.select([c for c in cols if c in rosters.columns]).head(8)
if rosters is not None else "rosters unavailable")

โœ… NFL.com rosters





shape: (8, 4)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ team_abbreviation โ”† team_full_name โ”† team_conference_abbr โ”† team_division_full_name โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† str โ”† str โ”† str โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ ARI โ”† Arizona Cardinals โ”† NFC โ”† NFC West โ”‚
โ”‚ ATL โ”† Atlanta Falcons โ”† NFC โ”† NFC South โ”‚
โ”‚ BAL โ”† Baltimore Ravens โ”† AFC โ”† AFC North โ”‚
โ”‚ BUF โ”† Buffalo Bills โ”† AFC โ”† AFC East โ”‚
โ”‚ CAR โ”† Carolina Panthers โ”† NFC โ”† NFC South โ”‚
โ”‚ CHI โ”† Chicago Bears โ”† NFC โ”† NFC North โ”‚
โ”‚ CIN โ”† Cincinnati Bengals โ”† AFC โ”† AFC North โ”‚
โ”‚ CLE โ”† Cleveland Browns โ”† AFC โ”† AFC North โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
weeks = safe("NFL.com weeks", lambda: nfl.nfl_weeks(season=SEASON, season_type="REG"))
cols = ["season", "week", "week_type", "date_begin", "date_end", "bye_teams"]
(weeks.select([c for c in cols if c in weeks.columns]).head(8)
if weeks is not None else "weeks unavailable")

โœ… NFL.com weeks





shape: (8, 6)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ season โ”† week โ”† week_type โ”† date_begin โ”† date_end โ”† bye_teams โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ i64 โ”† i64 โ”† str โ”† str โ”† str โ”† str โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ 2024 โ”† 18 โ”† REG โ”† 2025-01-01 โ”† 2025-01-08 โ”† [] โ”‚
โ”‚ 2024 โ”† 17 โ”† REG โ”† 2024-12-24 โ”† 2025-01-01 โ”† [] โ”‚
โ”‚ 2024 โ”† 16 โ”† REG โ”† 2024-12-18 โ”† 2024-12-24 โ”† [] โ”‚
โ”‚ 2024 โ”† 15 โ”† REG โ”† 2024-12-11 โ”† 2024-12-18 โ”† [] โ”‚
โ”‚ 2024 โ”† 14 โ”† REG โ”† 2024-12-04 โ”† 2024-12-11 โ”† [{'id': '10400325-48de-3d6a-beโ€ฆ โ”‚
โ”‚ 2024 โ”† 13 โ”† REG โ”† 2024-11-27 โ”† 2024-12-04 โ”† [] โ”‚
โ”‚ 2024 โ”† 12 โ”† REG โ”† 2024-11-20 โ”† 2024-11-27 โ”† [{'id': '10400200-f401-4e53-51โ€ฆ โ”‚
โ”‚ 2024 โ”† 11 โ”† REG โ”† 2024-11-13 โ”† 2024-11-20 โ”† [{'id': '10403800-517c-7b8c-65โ€ฆ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿฅ The weekly injury reportโ€‹

nfl_injuries is the official weekly injury report โ€” one row per listed player with their injury_status (Out / Doubtful / Questionable), practice participation, and team. This is the premium native feed, not a scrape.

inj = safe(
"NFL.com injuries",
lambda: nfl.nfl_injuries(season=SEASON, season_type="REG", week=1),
)
cols = [
"team_full_name", "person_display_name", "position",
"injuries", "injury_status", "practice_status",
]
(inj.select([c for c in cols if c in inj.columns]).head(10)
if inj is not None else "injuries unavailable")

โœ… NFL.com injuries





shape: (10, 6)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ team_full_name โ”† person_display_ โ”† position โ”† injuries โ”† injury_status โ”† practice_status โ”‚
โ”‚ --- โ”† name โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† --- โ”† str โ”† str โ”† str โ”† str โ”‚
โ”‚ โ”† str โ”† โ”† โ”† โ”† โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Atlanta Falcons โ”† Ta'Quon Graham โ”† DE โ”† [] โ”† null โ”† LIMITED โ”‚
โ”‚ Atlanta Falcons โ”† Antonio โ”† CB โ”† ['Groin'] โ”† OUT โ”† DIDNOT โ”‚
โ”‚ โ”† Hamilton โ”† โ”† โ”† โ”† โ”‚
โ”‚ Atlanta Falcons โ”† Grady Jarrett โ”† DT โ”† [] โ”† null โ”† DIDNOT โ”‚
โ”‚ Atlanta Falcons โ”† Nate Landman โ”† LB โ”† [] โ”† null โ”† FULL โ”‚
โ”‚ Atlanta Falcons โ”† Chris Lindstrom โ”† G โ”† ['Evaluated for โ”† null โ”† null โ”‚
โ”‚ โ”† โ”† โ”† a possible heaโ€ฆ โ”† โ”† โ”‚
โ”‚ Atlanta Falcons โ”† Jake Matthews โ”† T โ”† [] โ”† null โ”† LIMITED โ”‚
โ”‚ Atlanta Falcons โ”† David Onyemata โ”† DT โ”† [] โ”† null โ”† DIDNOT โ”‚
โ”‚ Atlanta Falcons โ”† Kyle Pitts โ”† TE โ”† [] โ”† null โ”† FULL โ”‚
โ”‚ Baltimore โ”† Rasheen Ali โ”† RB โ”† ['Neck'] โ”† DOUBTFUL โ”† LIMITED โ”‚
โ”‚ Ravens โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Baltimore โ”† Adisa Isaac โ”† LB โ”† ['Hamstring'] โ”† OUT โ”† DIDNOT โ”‚
โ”‚ Ravens โ”† โ”† โ”† โ”† โ”† โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“‹ Per-game details for a weekโ€‹

Need the full slate with drive charts, broadcast info and embedded standings? nfl_weekly_game_details returns one row per game for a week (toggle the heavy blocks with the include_* flags). For live in-game state (clock, down & distance, red-zone flags), reach for nfl_game_summaries.

wgd = safe(
"NFL.com weekly game details",
lambda: nfl.nfl_weekly_game_details(season=SEASON, season_type="REG", week=1),
)
cols = ["week", "date", "game_type", "away_team_full_name", "home_team_full_name", "status"]
(wgd.select([c for c in cols if c in wgd.columns]).head(8)
if wgd is not None else "weekly game details unavailable")

โœ… NFL.com weekly game details





shape: (8, 6)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ week โ”† date โ”† game_type โ”† away_team_full_name โ”† home_team_full_name โ”† status โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ i64 โ”† str โ”† str โ”† str โ”† str โ”† str โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ 1 โ”† 2024-09-06 โ”† UNSPECIFIED โ”† Baltimore Ravens โ”† Kansas City Chiefs โ”† SCHEDULED โ”‚
โ”‚ 1 โ”† 2024-09-07 โ”† UNSPECIFIED โ”† Green Bay Packers โ”† Philadelphia Eagles โ”† SCHEDULED โ”‚
โ”‚ 1 โ”† 2024-09-08 โ”† UNSPECIFIED โ”† Pittsburgh Steelers โ”† Atlanta Falcons โ”† SCHEDULED โ”‚
โ”‚ 1 โ”† 2024-09-08 โ”† UNSPECIFIED โ”† Arizona Cardinals โ”† Buffalo Bills โ”† SCHEDULED โ”‚
โ”‚ 1 โ”† 2024-09-08 โ”† UNSPECIFIED โ”† Tennessee Titans โ”† Chicago Bears โ”† SCHEDULED โ”‚
โ”‚ 1 โ”† 2024-09-08 โ”† UNSPECIFIED โ”† New England Patriots โ”† Cincinnati Bengals โ”† SCHEDULED โ”‚
โ”‚ 1 โ”† 2024-09-08 โ”† UNSPECIFIED โ”† Houston Texans โ”† Indianapolis Colts โ”† SCHEDULED โ”‚
โ”‚ 1 โ”† 2024-09-08 โ”† UNSPECIFIED โ”† Jacksonville Jaguars โ”† Miami Dolphins โ”† SCHEDULED โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โšก NextGen Stats: the tracking layerโ€‹

This is where it gets fun. The NFL's NextGen Stats API exposes player-tracking metrics you won't find in a box score โ€” time to throw, completion percentage over expectation (CPOE), separation, ball-carrier top speed. All token-free.

nfl_ngs_statboard is the season leaderboard. Ask for stat_type "passing", "rushing", or "receiving".

qb = safe(
"NGS passing statboard",
lambda: nfl.nfl_ngs_statboard(stat_type="passing", season=SEASON, season_type="REG"),
)
cols = [
"playerName", "passerRating", "completionPercentageAboveExpectation",
"avgTimeToThrow", "aggressiveness", "passYards", "passTouchdowns",
]
(qb.select([c for c in cols if c in qb.columns])
.sort("passerRating", descending=True)
.head(10)
if qb is not None and "passerRating" in qb.columns else "NGS statboard unavailable")

โœ… NGS passing statboard





shape: (10, 7)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ playerName โ”† passerRating โ”† completionPe โ”† avgTimeToTh โ”† aggressiven โ”† passYards โ”† passTouchdo โ”‚
โ”‚ --- โ”† --- โ”† rcentageAbov โ”† row โ”† ess โ”† --- โ”† wns โ”‚
โ”‚ str โ”† f64 โ”† eExpecโ€ฆ โ”† --- โ”† --- โ”† i64 โ”† --- โ”‚
โ”‚ โ”† โ”† --- โ”† f64 โ”† f64 โ”† โ”† i64 โ”‚
โ”‚ โ”† โ”† f64 โ”† โ”† โ”† โ”† โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Lamar โ”† 119.629044 โ”† -0.194641 โ”† 3.144269 โ”† 10.970464 โ”† 4172 โ”† 41 โ”‚
โ”‚ Jackson โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Jared Goff โ”† 111.769481 โ”† 5.054879 โ”† 2.787295 โ”† 11.502783 โ”† 4629 โ”† 37 โ”‚
โ”‚ Joe Burrow โ”† 108.537832 โ”† 4.521902 โ”† 2.710951 โ”† 15.797546 โ”† 4918 โ”† 43 โ”‚
โ”‚ Baker โ”† 106.761696 โ”† 2.17107 โ”† 2.6982 โ”† 10.877193 โ”† 4500 โ”† 41 โ”‚
โ”‚ Mayfield โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Jalen Hurts โ”† 103.687673 โ”† 6.305457 โ”† 3.1313 โ”† 16.34349 โ”† 2903 โ”† 18 โ”‚
โ”‚ Sam Darnold โ”† 102.534404 โ”† 2.799064 โ”† 3.083395 โ”† 13.944954 โ”† 4319 โ”† 35 โ”‚
โ”‚ Justin โ”† 101.703042 โ”† 2.391567 โ”† 2.910539 โ”† 15.873016 โ”† 3870 โ”† 23 โ”‚
โ”‚ Herbert โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Josh Allen โ”† 101.384576 โ”† 0.781139 โ”† 2.886884 โ”† 16.770186 โ”† 3731 โ”† 28 โ”‚
โ”‚ Tua โ”† 101.362782 โ”† 1.696667 โ”† 2.416476 โ”† 12.280702 โ”† 2867 โ”† 19 โ”‚
โ”‚ Tagovailoa โ”† โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ Derek Carr โ”† 101.022999 โ”† 3.222724 โ”† 2.758918 โ”† 11.111111 โ”† 2145 โ”† 15 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

And nfl_ngs_leaders serves the highlight-reel top-N boards โ€” each row is the play that earned the leader their spot. Categories include "speed" (fastest ball carriers), "yac_season" (yards-after-catch over expected), "completion_season" (most-improbable completions) and more.

fast = safe(
"NGS fastest ball carriers",
lambda: nfl.nfl_ngs_leaders(category="speed", season=SEASON, season_type="REG"),
)
cols = ["leader_playerName", "leader_teamAbbr", "leader_maxSpeed", "leader_yards", "play_playDescription"]
(fast.select([c for c in cols if c in fast.columns]).head(8)
if fast is not None else "NGS leaders unavailable")

โœ… NGS fastest ball carriers





shape: (8, 5)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ leader_playerName โ”† leader_teamAbbr โ”† leader_maxSpeed โ”† leader_yards โ”† play_playDescription โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† str โ”† f64 โ”† i64 โ”† str โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ KaVontae Turpin โ”† DAL โ”† 22.356818 โ”† 64 โ”† (15:00) (Shotgun) C.Rush โ”‚
โ”‚ โ”† โ”† โ”† โ”† pass โ€ฆ โ”‚
โ”‚ Brian Thomas Jr. โ”† JAX โ”† 22.152273 โ”† 85 โ”† (7:12) (Shotgun) โ”‚
โ”‚ โ”† โ”† โ”† โ”† T.Lawrence paโ€ฆ โ”‚
โ”‚ Jahmyr Gibbs โ”† DET โ”† 22.029546 โ”† 70 โ”† (4:07) (Shotgun) J.Gibbs โ”‚
โ”‚ โ”† โ”† โ”† โ”† left โ€ฆ โ”‚
โ”‚ Saquon Barkley โ”† PHI โ”† 21.927273 โ”† 55 โ”† (11:04) (No Huddle, โ”‚
โ”‚ โ”† โ”† โ”† โ”† Shotgun) Sโ€ฆ โ”‚
โ”‚ Saquon Barkley โ”† PHI โ”† 21.906818 โ”† 72 โ”† (2:54) (Shotgun) โ”‚
โ”‚ โ”† โ”† โ”† โ”† S.Barkley lefโ€ฆ โ”‚
โ”‚ Nico Collins โ”† HOU โ”† 21.886364 โ”† 55 โ”† (12:56) C.Stroud pass โ”‚
โ”‚ โ”† โ”† โ”† โ”† deep midโ€ฆ โ”‚
โ”‚ James Cook โ”† BUF โ”† 21.845455 โ”† 65 โ”† (8:48) A.Anderson โ”‚
โ”‚ โ”† โ”† โ”† โ”† reported in โ€ฆ โ”‚
โ”‚ KaVontae Turpin โ”† DAL โ”† 21.845455 โ”† 18 โ”† J.Elliott kicks 60 yards โ”‚
โ”‚ โ”† โ”† โ”† โ”† from โ€ฆ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“ฆ nflverse loaders: the bulk-data workhorsesโ€‹

For full-season modelling you want the nflverse release parquets โ€” the exact same assets that power nflfastR / nflreadr / nflreadpy. These are versioned, cached releases (very reliable), so we call them directly.

FunctionRowsHighlights
load_nfl_pbp~49k/seasonEPA, WP, air yards, 370+ columns
load_nfl_player_statsweeklypassing/rushing/receiving box lines
load_nfl_nextgen_statsweeklyNGS back to 2016
load_nfl_rostersper playerIDs, bios, draft info
pbp = nfl.load_nfl_pbp([SEASON])
pbp.shape

(49492, 372)
(pbp
.filter(pl.col("play_type").is_not_null())
.select(["game_id", "qtr", "down", "ydstogo", "posteam", "play_type", "yards_gained", "epa", "desc"])
.head(8))

shape: (8, 9)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ game_id โ”† qtr โ”† down โ”† ydstogo โ”† โ€ฆ โ”† play_type โ”† yards_gained โ”† epa โ”† desc โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† f64 โ”† f64 โ”† f64 โ”† โ”† str โ”† f64 โ”† f64 โ”† str โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ 2024_01_ARI_BU โ”† 1.0 โ”† null โ”† 0.0 โ”† โ€ฆ โ”† kickoff โ”† 0.0 โ”† 0.257819 โ”† 2-T.Bass โ”‚
โ”‚ F โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† kicks 65 โ”‚
โ”‚ โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† yards from Bโ€ฆ โ”‚
โ”‚ 2024_01_ARI_BU โ”† 1.0 โ”† 1.0 โ”† 10.0 โ”† โ€ฆ โ”† run โ”† 3.0 โ”† -0.200602 โ”† (15:00) โ”‚
โ”‚ F โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† 6-J.Conner up โ”‚
โ”‚ โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† the middโ€ฆ โ”‚
โ”‚ 2024_01_ARI_BU โ”† 1.0 โ”† 2.0 โ”† 7.0 โ”† โ€ฆ โ”† pass โ”† 22.0 โ”† 2.028874 โ”† (14:27) โ”‚
โ”‚ F โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† 1-K.Murray โ”‚
โ”‚ โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† pass short โ€ฆ โ”‚
โ”‚ 2024_01_ARI_BU โ”† 1.0 โ”† 1.0 โ”† 10.0 โ”† โ€ฆ โ”† pass โ”† 9.0 โ”† 0.754242 โ”† (13:43) โ”‚
โ”‚ F โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† (Shotgun) โ”‚
โ”‚ โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† 1-K.Murray pโ€ฆ โ”‚
โ”‚ 2024_01_ARI_BU โ”† 1.0 โ”† 2.0 โ”† 1.0 โ”† โ€ฆ โ”† run โ”† 2.0 โ”† -0.029602 โ”† (13:02) โ”‚
โ”‚ F โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† 6-J.Conner up โ”‚
โ”‚ โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† the middโ€ฆ โ”‚
โ”‚ 2024_01_ARI_BU โ”† 1.0 โ”† 1.0 โ”† 10.0 โ”† โ€ฆ โ”† run โ”† 2.0 โ”† -0.247749 โ”† (12:26) โ”‚
โ”‚ F โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† (Shotgun) โ”‚
โ”‚ โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† 6-J.Conner lโ€ฆ โ”‚
โ”‚ 2024_01_ARI_BU โ”† 1.0 โ”† 2.0 โ”† 8.0 โ”† โ€ฆ โ”† run โ”† 2.0 โ”† -0.530139 โ”† (11:51) โ”‚
โ”‚ F โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† 6-J.Conner โ”‚
โ”‚ โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† left end toโ€ฆ โ”‚
โ”‚ 2024_01_ARI_BU โ”† 1.0 โ”† 3.0 โ”† 6.0 โ”† โ€ฆ โ”† pass โ”† 8.0 โ”† 1.6808 โ”† (11:08) โ”‚
โ”‚ F โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† (Shotgun) โ”‚
โ”‚ โ”† โ”† โ”† โ”† โ”† โ”† โ”† โ”† 1-K.Murray pโ€ฆ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
ngs_release = nfl.load_nfl_nextgen_stats([SEASON], stat_type="passing")
(ngs_release
.filter(pl.col("week") == 0) # week 0 == season totals in this release
.select(["player_display_name", "team_abbr", "attempts", "pass_yards",
"completion_percentage_above_expectation", "passer_rating"])
.sort("passer_rating", descending=True)
.head(8))

shape: (8, 6)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ player_display_name โ”† team_abbr โ”† attempts โ”† pass_yards โ”† completion_percentage_ โ”† passer_rating โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† above_exโ€ฆ โ”† --- โ”‚
โ”‚ str โ”† str โ”† i32 โ”† i32 โ”† --- โ”† f64 โ”‚
โ”‚ โ”† โ”† โ”† โ”† f64 โ”† โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Lamar Jackson โ”† BAL โ”† 474 โ”† 4172 โ”† -0.194641 โ”† 119.629044 โ”‚
โ”‚ Jared Goff โ”† DET โ”† 539 โ”† 4629 โ”† 5.054879 โ”† 111.769481 โ”‚
โ”‚ Joe Burrow โ”† CIN โ”† 652 โ”† 4918 โ”† 4.521902 โ”† 108.537832 โ”‚
โ”‚ Baker Mayfield โ”† TB โ”† 570 โ”† 4500 โ”† 2.17107 โ”† 106.761696 โ”‚
โ”‚ Jalen Hurts โ”† PHI โ”† 361 โ”† 2903 โ”† 6.305457 โ”† 103.687673 โ”‚
โ”‚ Sam Darnold โ”† MIN โ”† 545 โ”† 4319 โ”† 2.799064 โ”† 102.534404 โ”‚
โ”‚ Justin Herbert โ”† LAC โ”† 504 โ”† 3870 โ”† 2.391567 โ”† 101.703042 โ”‚
โ”‚ Josh Allen โ”† BUF โ”† 483 โ”† 3731 โ”† 0.781139 โ”† 101.384576 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”ต Secondary path: ESPN (quick & no-auth)โ€‹

When you just want a fast scoreboard without minting a token, ESPN is right there. espn_nfl_schedule returns a tidy schedule frame; pass dates=YYYYMMDD for a single day. (There's also a raw espn_nfl_scoreboard if you want the unparsed JSON.)

espn_sched = safe("ESPN schedule", lambda: nfl.espn_nfl_schedule(dates=20240908))
cols = ["id", "away_display_name", "home_display_name", "away_score", "home_score", "status_type_description"]
(espn_sched.select([c for c in cols if c in espn_sched.columns]).head(8)
if espn_sched is not None else "ESPN schedule unavailable")

โœ… ESPN schedule





shape: (8, 6)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ id โ”† away_display_name โ”† home_display_name โ”† away_score โ”† home_score โ”† status_type_descr โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† iption โ”‚
โ”‚ str โ”† str โ”† str โ”† str โ”† str โ”† --- โ”‚
โ”‚ โ”† โ”† โ”† โ”† โ”† str โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ 401671744 โ”† Pittsburgh โ”† Atlanta Falcons โ”† 18 โ”† 10 โ”† Final โ”‚
โ”‚ โ”† Steelers โ”† โ”† โ”† โ”† โ”‚
โ”‚ 401671617 โ”† Arizona Cardinals โ”† Buffalo Bills โ”† 28 โ”† 34 โ”† Final โ”‚
โ”‚ 401671719 โ”† Tennessee Titans โ”† Chicago Bears โ”† 17 โ”† 24 โ”† Final โ”‚
โ”‚ 401671628 โ”† New England โ”† Cincinnati โ”† 16 โ”† 10 โ”† Final โ”‚
โ”‚ โ”† Patriots โ”† Bengals โ”† โ”† โ”† โ”‚
โ”‚ 401671861 โ”† Houston Texans โ”† Indianapolis โ”† 29 โ”† 27 โ”† Final โ”‚
โ”‚ โ”† โ”† Colts โ”† โ”† โ”† โ”‚
โ”‚ 401671849 โ”† Jacksonville โ”† Miami Dolphins โ”† 17 โ”† 20 โ”† Final โ”‚
โ”‚ โ”† Jaguars โ”† โ”† โ”† โ”† โ”‚
โ”‚ 401671734 โ”† Carolina Panthers โ”† New Orleans โ”† 10 โ”† 47 โ”† Final โ”‚
โ”‚ โ”† โ”† Saints โ”† โ”† โ”† โ”‚
โ”‚ 401671712 โ”† Minnesota Vikings โ”† New York Giants โ”† 28 โ”† 6 โ”† Final โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿณ Cookbook: common NFL tasksโ€‹

A full dozen recipes you'll reach for constantly โ€” leaderboards, splits, team-level efficiency, snap-share workhorses, play-by-play slices, a schedule scan, and a quick hop into pandas. Each one leans on the premium native/NextGen feeds or the rock-solid nflverse release parquets, and every live call is wrapped so a network blip never breaks your run. Recipes 1โ€“4 use the live NFL.com / NextGen endpoints; 5โ€“12 build on the cached release parquets, so they run anywhere, anytime. ๐Ÿˆ

Recipe 1 โ€” This week's "Out" list ๐Ÿš‘โ€‹

Filter the official injury report down to players ruled Out โ€” exactly what you'd check before setting a lineup.

rep = safe(
"injury report",
lambda: nfl.nfl_injuries(season=SEASON, season_type="REG", week=1),
)
if rep is not None and rep.height and "injury_status" in rep.columns:
out = (
rep.filter(pl.col("injury_status").str.to_lowercase() == "out")
.select([c for c in ["team_full_name", "person_display_name", "position", "injuries"]
if c in rep.columns])
.head(15)
)
else:
out = "injury report unavailable"
out

โœ… injury report





shape: (5, 4)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ team_full_name โ”† person_display_name โ”† position โ”† injuries โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† str โ”† str โ”† str โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Atlanta Falcons โ”† Antonio Hamilton โ”† CB โ”† ['Groin'] โ”‚
โ”‚ Baltimore Ravens โ”† Adisa Isaac โ”† LB โ”† ['Hamstring'] โ”‚
โ”‚ Baltimore Ravens โ”† Kyle Van Noy โ”† LB โ”† ['gameday concussion protocol โ€ฆ โ”‚
โ”‚ Buffalo Bills โ”† Taron Johnson โ”† CB โ”† ['Forearm'] โ”‚
โ”‚ Buffalo Bills โ”† Javon Solomon โ”† DE โ”† ['Oblique'] โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 2 โ€” CPOE leaderboard from NextGen Stats ๐ŸŽฏโ€‹

Who's beating expectation as a passer? Rank qualified QBs by completion percentage above expectation straight off the NextGen statboard.

board = safe(
"NGS passing board",
lambda: nfl.nfl_ngs_statboard(stat_type="passing", season=SEASON, season_type="REG"),
)
if board is not None and board.height and "completionPercentageAboveExpectation" in board.columns:
cpoe = (
board.filter(pl.col("attempts") >= 200)
.select(["playerName", "attempts", "completionPercentage",
"completionPercentageAboveExpectation", "passerRating"])
.sort("completionPercentageAboveExpectation", descending=True)
.head(10)
)
else:
cpoe = "NGS board unavailable"
cpoe

โœ… NGS passing board





shape: (10, 5)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ playerName โ”† attempts โ”† completionPercentage โ”† completionPercentageAboveExpec โ”† passerRating โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† โ€ฆ โ”† --- โ”‚
โ”‚ str โ”† i64 โ”† f64 โ”† --- โ”† f64 โ”‚
โ”‚ โ”† โ”† โ”† f64 โ”† โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Jalen Hurts โ”† 361 โ”† 68.698061 โ”† 6.305457 โ”† 103.687673 โ”‚
โ”‚ Jared Goff โ”† 539 โ”† 72.356215 โ”† 5.054879 โ”† 111.769481 โ”‚
โ”‚ Joe Burrow โ”† 652 โ”† 70.552147 โ”† 4.521902 โ”† 108.537832 โ”‚
โ”‚ Geno Smith โ”† 578 โ”† 70.415225 โ”† 3.854464 โ”† 93.202134 โ”‚
โ”‚ Kirk Cousins โ”† 453 โ”† 66.887417 โ”† 3.442009 โ”† 88.61755 โ”‚
โ”‚ Derek Carr โ”† 279 โ”† 67.741935 โ”† 3.222724 โ”† 101.022999 โ”‚
โ”‚ Drake Maye โ”† 338 โ”† 66.568047 โ”† 2.986893 โ”† 88.079389 โ”‚
โ”‚ Brock Purdy โ”† 455 โ”† 65.934066 โ”† 2.983077 โ”† 96.076007 โ”‚
โ”‚ Sam Darnold โ”† 545 โ”† 66.238532 โ”† 2.799064 โ”† 102.534404 โ”‚
โ”‚ Justin Herbert โ”† 504 โ”† 65.873016 โ”† 2.391567 โ”† 101.703042 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 3 โ€” Standings โ†’ division winners ๐Ÿ†โ€‹

Take the premium standings and pull the team that tops each division. One group-by and you've got your playoff-seeding cheat sheet.

st = safe(
"standings",
lambda: nfl.nfl_standings(season=SEASON, season_type="REG", week=18),
)
if st is not None and st.height and {"division_rank", "team_full_name"}.issubset(st.columns):
div_col = next((c for c in ["team_division_full_name", "division_full_name", "division"] if c in st.columns), None)
keep = [c for c in [div_col, "team_full_name", "overall_wins", "overall_losses"] if c]
winners = (
st.filter(pl.col("division_rank") == 1)
.select(keep)
.sort(div_col) if div_col else st.filter(pl.col("division_rank") == 1).select(keep)
)
else:
winners = "standings unavailable"
winners

โœ… standings





shape: (8, 3)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ team_full_name โ”† overall_wins โ”† overall_losses โ”‚
โ”‚ --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† i64 โ”† i64 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Baltimore Ravens โ”† 12 โ”† 5 โ”‚
โ”‚ Buffalo Bills โ”† 13 โ”† 4 โ”‚
โ”‚ Detroit Lions โ”† 15 โ”† 2 โ”‚
โ”‚ Houston Texans โ”† 10 โ”† 7 โ”‚
โ”‚ Kansas City Chiefs โ”† 15 โ”† 2 โ”‚
โ”‚ Los Angeles Rams โ”† 10 โ”† 7 โ”‚
โ”‚ Philadelphia Eagles โ”† 14 โ”† 3 โ”‚
โ”‚ Tampa Bay Buccaneers โ”† 10 โ”† 7 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 4 โ€” A game's NextGen passer splits ๐Ÿ”ฌโ€‹

Grab an NGS gameId from the schedule, then pull nfl_ngs_gamecenter_overview to see each side's primary passer with tracking-derived splits.

sched = safe(
"NGS schedule",
lambda: nfl.nfl_ngs_league_schedule(season=SEASON, season_type="REG", week=1),
)
if sched is not None and sched.height and "gameId" in sched.columns:
gid = sched["gameId"][0]
ov = safe(f"NGS gamecenter {gid}",
lambda: nfl.nfl_ngs_gamecenter_overview(game_id=gid, group="passers"))
if ov is not None and ov.height:
out = ov.select([c for c in ["side", "teamAbbr", "playerName", "position",
"completions", "attempts", "passYards", "touchdowns"]
if c in ov.columns])
else:
out = "gamecenter unavailable"
else:
out = "NGS schedule unavailable"
out

โœ… NGS schedule


โœ… NGS gamecenter 2024090500





shape: (2, 8)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ side โ”† teamAbbr โ”† playerName โ”† position โ”† completions โ”† attempts โ”† passYards โ”† touchdowns โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† str โ”† str โ”† str โ”† i64 โ”† i64 โ”† i64 โ”† i64 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ home โ”† KC โ”† Patrick โ”† QB โ”† 20 โ”† 28 โ”† 291 โ”† 1 โ”‚
โ”‚ โ”† โ”† Mahomes โ”† โ”† โ”† โ”† โ”† โ”‚
โ”‚ visitor โ”† BAL โ”† Lamar Jackson โ”† QB โ”† 26 โ”† 41 โ”† 273 โ”† 1 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 5 โ€” Season rushing leaders ๐Ÿƒโ€‹

Roll the weekly box scores in load_nfl_player_stats up to season totals and crown the ground-game kings (โ‰ฅ150 carries).

ps = nfl.load_nfl_player_stats()
rush_cols = {"season", "season_type", "carries", "rushing_yards"}
if rush_cols.issubset(ps.columns):
rush_lb = (
ps.filter((pl.col("season") == SEASON) & (pl.col("season_type") == "REG"))
.group_by(["player_display_name", "recent_team"])
.agg(
pl.col("carries").sum().alias("carries"),
pl.col("rushing_yards").sum().alias("rush_yds"),
pl.col("rushing_tds").sum().alias("rush_td"),
pl.col("rushing_epa").sum().round(1).alias("rush_epa"),
)
.filter(pl.col("carries") >= 150)
.sort("rush_yds", descending=True)
.head(10)
)
else:
rush_lb = "player_stats schema changed โ€” rushing columns missing"
rush_lb
shape: (10, 6)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ player_display_name โ”† recent_team โ”† carries โ”† rush_yds โ”† rush_td โ”† rush_epa โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† str โ”† i32 โ”† f64 โ”† i32 โ”† f64 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Saquon Barkley โ”† PHI โ”† 345 โ”† 2005.0 โ”† 13 โ”† 34.1 โ”‚
โ”‚ Derrick Henry โ”† BAL โ”† 325 โ”† 1921.0 โ”† 16 โ”† 40.6 โ”‚
โ”‚ Bijan Robinson โ”† ATL โ”† 304 โ”† 1456.0 โ”† 14 โ”† 16.9 โ”‚
โ”‚ Jonathan Taylor โ”† IND โ”† 303 โ”† 1431.0 โ”† 11 โ”† -21.0 โ”‚
โ”‚ Jahmyr Gibbs โ”† DET โ”† 250 โ”† 1412.0 โ”† 16 โ”† 35.1 โ”‚
โ”‚ Josh Jacobs โ”† GB โ”† 301 โ”† 1329.0 โ”† 15 โ”† -18.3 โ”‚
โ”‚ Kyren Williams โ”† LA โ”† 316 โ”† 1299.0 โ”† 14 โ”† -23.5 โ”‚
โ”‚ Chuba Hubbard โ”† CAR โ”† 250 โ”† 1195.0 โ”† 10 โ”† 9.7 โ”‚
โ”‚ Aaron Jones โ”† MIN โ”† 255 โ”† 1138.0 โ”† 5 โ”† -13.4 โ”‚
โ”‚ Bucky Irving โ”† TB โ”† 207 โ”† 1122.0 โ”† 8 โ”† 20.9 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 6 โ€” The most efficient offenses (EPA/play) ๐Ÿ“ˆโ€‹

Expected points added is the modeller's favourite efficiency yardstick. Average epa over every run/pass in load_nfl_pbp to rank offenses.

pbp = nfl.load_nfl_pbp([SEASON])
if {"epa", "posteam", "play_type"}.issubset(pbp.columns):
epa_off = (
pbp.filter(pl.col("play_type").is_in(["run", "pass"]))
.group_by("posteam")
.agg(
pl.col("epa").mean().round(3).alias("epa_per_play"),
pl.len().alias("plays"),
)
.filter(pl.col("posteam").is_not_null())
.sort("epa_per_play", descending=True)
.head(10)
)
else:
epa_off = "pbp schema changed โ€” epa/posteam columns missing"
epa_off
shape: (10, 3)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ posteam โ”† epa_per_play โ”† plays โ”‚
โ”‚ --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† f64 โ”† u32 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ BAL โ”† 0.219 โ”† 1167 โ”‚
โ”‚ BUF โ”† 0.19 โ”† 1202 โ”‚
โ”‚ DET โ”† 0.165 โ”† 1164 โ”‚
โ”‚ WAS โ”† 0.132 โ”† 1308 โ”‚
โ”‚ TB โ”† 0.129 โ”† 1128 โ”‚
โ”‚ PHI โ”† 0.119 โ”† 1341 โ”‚
โ”‚ CIN โ”† 0.09 โ”† 1069 โ”‚
โ”‚ GB โ”† 0.071 โ”† 1081 โ”‚
โ”‚ SF โ”† 0.069 โ”† 1014 โ”‚
โ”‚ ARI โ”† 0.067 โ”† 1031 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 7 โ€” Third-down conversion kings ๐Ÿ”‘โ€‹

Move-the-chains efficiency: keep only 3rd-down run/pass snaps and divide conversions by attempts per offense โ€” a classic play-by-play split.

if {"down", "third_down_converted", "posteam"}.issubset(pbp.columns):
third = (
pbp.filter((pl.col("down") == 3) & (pl.col("play_type").is_in(["run", "pass"])))
.group_by("posteam")
.agg(
pl.col("third_down_converted").sum().alias("conversions"),
pl.len().alias("attempts"),
)
.filter(pl.col("posteam").is_not_null())
.with_columns((pl.col("conversions") / pl.col("attempts") * 100).round(1).alias("conv_pct"))
.sort("conv_pct", descending=True)
.head(10)
)
else:
third = "pbp schema changed โ€” third-down columns missing"
third
shape: (10, 4)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ posteam โ”† conversions โ”† attempts โ”† conv_pct โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† f64 โ”† u32 โ”† f64 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ TB โ”† 115.0 โ”† 226 โ”† 50.9 โ”‚
โ”‚ BAL โ”† 109.0 โ”† 214 โ”† 50.9 โ”‚
โ”‚ KC โ”† 123.0 โ”† 255 โ”† 48.2 โ”‚
โ”‚ DET โ”† 101.0 โ”† 213 โ”† 47.4 โ”‚
โ”‚ CIN โ”† 100.0 โ”† 214 โ”† 46.7 โ”‚
โ”‚ BUF โ”† 107.0 โ”† 237 โ”† 45.1 โ”‚
โ”‚ WAS โ”† 118.0 โ”† 262 โ”† 45.0 โ”‚
โ”‚ ARI โ”† 83.0 โ”† 192 โ”† 43.2 โ”‚
โ”‚ SF โ”† 84.0 โ”† 196 โ”† 42.9 โ”‚
โ”‚ PHI โ”† 114.0 โ”† 278 โ”† 41.0 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 8 โ€” Red-zone touchdown efficiency ๐ŸŽฏโ€‹

Filter the play-by-play to snaps inside the opponent's 20 (yardline_100 โ‰ค 20) and see which offenses actually punch it in instead of settling for three.

if {"yardline_100", "touchdown", "posteam"}.issubset(pbp.columns):
redzone = (
pbp.filter((pl.col("yardline_100") <= 20) & (pl.col("play_type").is_in(["run", "pass"])))
.group_by("posteam")
.agg(
pl.col("touchdown").sum().alias("rz_tds"),
pl.len().alias("rz_plays"),
)
.filter((pl.col("posteam").is_not_null()) & (pl.col("rz_plays") >= 80))
.with_columns((pl.col("rz_tds") / pl.col("rz_plays") * 100).round(1).alias("td_pct"))
.sort("td_pct", descending=True)
.head(10)
)
else:
redzone = "pbp schema changed โ€” red-zone columns missing"
redzone
shape: (10, 4)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ posteam โ”† rz_tds โ”† rz_plays โ”† td_pct โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† f64 โ”† u32 โ”† f64 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ BAL โ”† 55.0 โ”† 178 โ”† 30.9 โ”‚
โ”‚ TB โ”† 47.0 โ”† 175 โ”† 26.9 โ”‚
โ”‚ BUF โ”† 55.0 โ”† 232 โ”† 23.7 โ”‚
โ”‚ DEN โ”† 36.0 โ”† 157 โ”† 22.9 โ”‚
โ”‚ DET โ”† 54.0 โ”† 239 โ”† 22.6 โ”‚
โ”‚ GB โ”† 43.0 โ”† 195 โ”† 22.1 โ”‚
โ”‚ SEA โ”† 27.0 โ”† 125 โ”† 21.6 โ”‚
โ”‚ NO โ”† 25.0 โ”† 120 โ”† 20.8 โ”‚
โ”‚ NYJ โ”† 31.0 โ”† 150 โ”† 20.7 โ”‚
โ”‚ ARI โ”† 32.0 โ”† 157 โ”† 20.4 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 9 โ€” Snap-share workhorse running backs ๐Ÿดโ€‹

load_nfl_snap_counts carries offense_pct per game โ€” average it to find the backs their teams simply would not take off the field.

snaps = nfl.load_nfl_snap_counts([SEASON])
if {"position", "offense_pct", "player"}.issubset(snaps.columns):
workhorses = (
snaps.filter(pl.col("position") == "RB")
.group_by(["player", "team"])
.agg(
(pl.col("offense_pct").mean() * 100).round(1).alias("avg_snap_pct"),
pl.len().alias("games"),
)
.filter(pl.col("games") >= 10)
.sort("avg_snap_pct", descending=True)
.head(10)
)
else:
workhorses = "snap_counts schema changed โ€” offense_pct/position missing"
workhorses
shape: (10, 4)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ player โ”† team โ”† avg_snap_pct โ”† games โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† str โ”† f64 โ”† u32 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Kyren Williams โ”† LA โ”† 87.2 โ”† 18 โ”‚
โ”‚ Jonathan Taylor โ”† IND โ”† 80.3 โ”† 14 โ”‚
โ”‚ Chuba Hubbard โ”† CAR โ”† 77.3 โ”† 15 โ”‚
โ”‚ Bijan Robinson โ”† ATL โ”† 75.4 โ”† 17 โ”‚
โ”‚ Saquon Barkley โ”† PHI โ”† 75.1 โ”† 20 โ”‚
โ”‚ Breece Hall โ”† NYJ โ”† 72.4 โ”† 16 โ”‚
โ”‚ Alvin Kamara โ”† NO โ”† 70.9 โ”† 14 โ”‚
โ”‚ Tony Pollard โ”† TEN โ”† 67.8 โ”† 16 โ”‚
โ”‚ D'Andre Swift โ”† CHI โ”† 66.8 โ”† 17 โ”‚
โ”‚ Aaron Jones โ”† MIN โ”† 63.7 โ”† 18 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 10 โ€” Receiving leaders, then a hop into pandas ๐Ÿผโ€‹

Aggregate the receiving box lines, .to_pandas(), and add derived columns (yards-per-catch, catch rate) with familiar pandas syntax โ€” the polarsโ†’pandas handoff is one method call.

rec_cols = {"receptions", "receiving_yards", "targets", "season", "season_type"}
if rec_cols.issubset(ps.columns):
rec = (
ps.filter((pl.col("season") == SEASON) & (pl.col("season_type") == "REG"))
.group_by(["player_display_name", "recent_team"])
.agg(
pl.col("receptions").sum().alias("rec"),
pl.col("receiving_yards").sum().alias("rec_yds"),
pl.col("targets").sum().alias("tgt"),
)
.filter(pl.col("rec") >= 70)
)
pdf = rec.to_pandas() # <-- polars -> pandas in one call
pdf["yards_per_rec"] = (pdf["rec_yds"] / pdf["rec"]).round(1)
pdf["catch_rate"] = (pdf["rec"] / pdf["tgt"] * 100).round(1)
rec_out = pdf.sort_values("rec_yds", ascending=False).head(10)[
["player_display_name", "recent_team", "rec", "rec_yds", "yards_per_rec", "catch_rate"]
].reset_index(drop=True)
else:
rec_out = "player_stats schema changed โ€” receiving columns missing"
rec_out
player_display_name recent_team rec rec_yds yards_per_rec catch_rate
0 Ja'Marr Chase CIN 127 1708.0 13.4 72.6
1 Justin Jefferson MIN 103 1533.0 14.9 66.9
2 Brian Thomas JAX 87 1282.0 14.7 65.4
3 Drake London ATL 100 1271.0 12.7 63.3
4 Amon-Ra St. Brown DET 115 1263.0 11.0 81.6
5 Jerry Jeudy CLE 90 1229.0 13.7 62.1
6 Malik Nabers NYG 109 1204.0 11.0 64.1
7 CeeDee Lamb DAL 101 1194.0 11.8 66.4
8 Brock Bowers LV 112 1194.0 10.7 73.2
9 Ladd McConkey LAC 82 1149.0 14.0 73.2

Recipe 11 โ€” Who gets open? NextGen separation ๐Ÿ›ฐ๏ธโ€‹

The receiving statboard exposes a tracking-only metric box scores can't: average separation at the catch point. Rank qualified targets (โ‰ฅ80) to find the route-runners defenders can't shadow.

sepboard = safe(
"NGS receiving statboard",
lambda: nfl.nfl_ngs_statboard(stat_type="receiving", season=SEASON, season_type="REG"),
)
if sepboard is not None and sepboard.height and "avgSeparation" in sepboard.columns:
sep = (
sepboard.filter(pl.col("targets") >= 80)
.select([c for c in [
"player_displayName", "player_position", "avgSeparation",
"avgYACAboveExpectation", "catchPercentage", "yards",
] if c in sepboard.columns])
.sort("avgSeparation", descending=True)
.head(10)
)
else:
sep = "NGS receiving statboard unavailable"
sep
โœ… NGS receiving statboard





shape: (10, 6)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ player_displayNam โ”† player_position โ”† avgSeparation โ”† avgYACAboveExpec โ”† catchPercentage โ”† yards โ”‚
โ”‚ e โ”† --- โ”† --- โ”† tation โ”† --- โ”† --- โ”‚
โ”‚ --- โ”† str โ”† f64 โ”† --- โ”† f64 โ”† i64 โ”‚
โ”‚ str โ”† โ”† โ”† f64 โ”† โ”† โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ Khalil Shakir โ”† WR โ”† 4.253744 โ”† 1.420359 โ”† 76.0 โ”† 821 โ”‚
โ”‚ Demario Douglas โ”† WR โ”† 4.010062 โ”† 0.298947 โ”† 75.862069 โ”† 621 โ”‚
โ”‚ Zay Flowers โ”† WR โ”† 3.9155 โ”† 1.636763 โ”† 63.793103 โ”† 1059 โ”‚
โ”‚ Xavier Worthy โ”† WR โ”† 3.773458 โ”† 0.445979 โ”† 60.204082 โ”† 638 โ”‚
โ”‚ Zach Ertz โ”† TE โ”† 3.631374 โ”† -0.207435 โ”† 72.527473 โ”† 654 โ”‚
โ”‚ George Kittle โ”† TE โ”† 3.582076 โ”† 2.110873 โ”† 82.978723 โ”† 1106 โ”‚
โ”‚ Sam LaPorta โ”† TE โ”† 3.529115 โ”† 1.433347 โ”† 72.289157 โ”† 726 โ”‚
โ”‚ Brock Bowers โ”† TE โ”† 3.515527 โ”† 0.982977 โ”† 73.202614 โ”† 1194 โ”‚
โ”‚ Trey McBride โ”† TE โ”† 3.511888 โ”† 0.637703 โ”† 75.510204 โ”† 1146 โ”‚
โ”‚ Jonnu Smith โ”† TE โ”† 3.49632 โ”† 0.848143 โ”† 79.279279 โ”† 884 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Recipe 12 โ€” The nail-biters: closest games of the season ๐Ÿ˜ฌโ€‹

load_nfl_schedule carries the final result (home margin). Take its absolute value and sort ascending to surface the one-score thrillers โ€” built-in betting lines ride along too.

sched = nfl.load_nfl_schedule([SEASON])
if {"result", "game_type", "home_team", "away_team"}.issubset(sched.columns):
scored = (
sched.filter((pl.col("game_type") == "REG") & pl.col("result").is_not_null())
.with_columns(pl.col("result").abs().alias("margin"))
)
want = [
"week", "away_team", "away_score", "home_team", "home_score",
"margin", "spread_line", "total_line",
]
nailbiters = (
scored.select([c for c in want if c in scored.columns])
.sort("margin")
.head(10)
)
else:
nailbiters = "schedule schema changed โ€” result/team columns missing"
nailbiters
shape: (10, 8)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ week โ”† away_team โ”† away_score โ”† home_team โ”† home_score โ”† margin โ”† spread_line โ”† total_line โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ i32 โ”† str โ”† i32 โ”† str โ”† i32 โ”† i32 โ”† f64 โ”† f64 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ 2 โ”† CIN โ”† 25 โ”† KC โ”† 26 โ”† 1 โ”† 6.5 โ”† 47.5 โ”‚
โ”‚ 2 โ”† ATL โ”† 22 โ”† PHI โ”† 21 โ”† 1 โ”† 5.5 โ”† 46.5 โ”‚
โ”‚ 4 โ”† DEN โ”† 10 โ”† NYJ โ”† 9 โ”† 1 โ”† 7.5 โ”† 39.5 โ”‚
โ”‚ 5 โ”† ARI โ”† 24 โ”† SF โ”† 23 โ”† 1 โ”† 7.0 โ”† 48.5 โ”‚
โ”‚ 8 โ”† ARI โ”† 28 โ”† MIA โ”† 27 โ”† 1 โ”† 4.0 โ”† 46.5 โ”‚
โ”‚ 9 โ”† NO โ”† 22 โ”† CAR โ”† 23 โ”† 1 โ”† -7.0 โ”† 43.5 โ”‚
โ”‚ 10 โ”† CIN โ”† 34 โ”† BAL โ”† 35 โ”† 1 โ”† 6.0 โ”† 53.0 โ”‚
โ”‚ 10 โ”† PIT โ”† 28 โ”† WAS โ”† 27 โ”† 1 โ”† 1.5 โ”† 45.0 โ”‚
โ”‚ 11 โ”† GB โ”† 20 โ”† CHI โ”† 19 โ”† 1 โ”† -6.0 โ”† 41.0 โ”‚
โ”‚ 11 โ”† IND โ”† 28 โ”† NYJ โ”† 27 โ”† 1 โ”† 4.0 โ”† 43.0 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ—“๏ธ Season helpersโ€‹

Handy when you want "the current/most-recent season" instead of hard-coding a year. get_current_nfl_season() / get_current_nfl_week() track the live calendar; most_recent_nfl_season() gives the latest season with data.

{
"current_season": nfl.get_current_nfl_season(),
"current_week": nfl.get_current_nfl_week(),
"most_recent_season": nfl.most_recent_nfl_season(),
}

{'current_season': 2025, 'current_week': 22, 'most_recent_season': 2025}

๐Ÿ† Season standings + playoff seeding โ€” nfl_season_standingsโ€‹

New in 0.0.72: a faithful port of the nflseedR v2 standings engine. It computes division ranks, conference seeds, and the full tiebreaker cascade straight from a games frame โ€” the schedule loader output works as-is:

from sportsdataverse.nfl import load_nfl_schedule, nfl_season_standings

standings = nfl_season_standings(load_nfl_schedule(seasons=[2024]))
print("2024 standings:", standings.shape)
standings.select(["team", "division", "games", "wins", "losses", "true_wins"]).head(8)
2024 standings: (32, 21)





shape: (8, 6)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ team โ”† division โ”† games โ”† wins โ”† losses โ”† true_wins โ”‚
โ”‚ --- โ”† --- โ”† --- โ”† --- โ”† --- โ”† --- โ”‚
โ”‚ str โ”† str โ”† i64 โ”† f64 โ”† i64 โ”† i64 โ”‚
โ•žโ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
โ”‚ BUF โ”† AFC East โ”† 17 โ”† 13.0 โ”† 4 โ”† 13 โ”‚
โ”‚ MIA โ”† AFC East โ”† 17 โ”† 8.0 โ”† 9 โ”† 8 โ”‚
โ”‚ NYJ โ”† AFC East โ”† 17 โ”† 5.0 โ”† 12 โ”† 5 โ”‚
โ”‚ NE โ”† AFC East โ”† 17 โ”† 4.0 โ”† 13 โ”† 4 โ”‚
โ”‚ BAL โ”† AFC North โ”† 17 โ”† 12.0 โ”† 5 โ”† 12 โ”‚
โ”‚ PIT โ”† AFC North โ”† 17 โ”† 10.0 โ”† 7 โ”† 10 โ”‚
โ”‚ CIN โ”† AFC North โ”† 17 โ”† 9.0 โ”† 8 โ”† 9 โ”‚
โ”‚ CLE โ”† AFC North โ”† 17 โ”† 3.0 โ”† 14 โ”† 3 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐ŸŽ‰ Where to nextโ€‹

Now go build something great โ€” may your EPA be ever positive! ๐Ÿ“ˆ๐Ÿˆ