NFL data in Python: load the games CSV with pandas
Two lines of pandas load the NFL sample and print its size:
import pandas as pd
games = pd.read_csv("https://jayjex.github.io/data-vault/data/nfl-games/sample.csv")
print(games.shape) # (22, 46)
The file is 46 columns and 22 data rows, one row per game, weeks 1 and 2 of the 1999 season. read_csv accepts the URL directly, so nothing to download first, no signup, no API key. The three analyses below were run against that exact URL; every number shown in the output comments comes from the real file.
Setup
pandas is the only package the quickstart needs. Install it once:
pip install pandas
Then work in a Jupyter notebook, an IPython session, or a plain script. Reading a URL instead of a local path means the same two lines work on any machine with network access. If you would rather pin a local copy, download the sample CSV and point read_csv at the filename.
Load the sample and check it
The conventions worth one glance before the analyses:
import pandas as pd
url = "https://jayjex.github.io/data-vault/data/nfl-games/sample.csv"
games = pd.read_csv(url, dtype={"game_id": str})
print(games.shape) # (22, 46)
print(games.loc[0, "game_id"]) # 1999_01_MIN_ATL
print(games["temp"].dtype) # float64
game_idis the join key in season_week_AWAY_HOME format, like1999_01_MIN_ATL. Thedtypeargument holds it as a string; the_characters would force that reading anyway, and the argument makes the type certain.tempandwindarrive asfloat64because the 6 dome games have blank cells. Blank becomes NaN, and a numeric column containing NaN cannot stay int64. The full column list lives in the games.csv column guide.spread_lineis stored relative to the home team: -4 means the away team is favored by 4.
Three small analyses
1. Who won more, home or away teams?
home_wins = (games["home_score"] > games["away_score"]).sum() away_wins = (games["away_score"] > games["home_score"]).sum() print(home_wins, away_wins) # 10 12
The 22 games split 10 home wins and 12 away wins, no ties. A quick reality check for anyone modeling home-field advantage: in this early-September window the road teams won more, which is exactly why 22 rows teach pandas and not trends. The full pack carries all 7,548 games if you want to test the home-edge question properly.
2. Dome vs outdoor scoring
scoring = games.groupby("roof")["total"].agg(["count", "mean"]).round(1)
print(scoring)
# count mean
# roof
# dome 6 38.0
# outdoors 16 45.5
total is combined points. The 6 dome games averaged 38.0, the 16 outdoor games 45.5. The count column keeps the sample-size gap visible: 6 rows is a handful, so treat the gap as a pandas exercise, not a finding. On the full file the same groupby runs across 27 seasons. The roof split is one slice of the weather story; NFL stadium weather, read from the same columns covers temp, wind, and what the file can and cannot say about kicking.
3. The hottest kickoffs and what those games scored
hot = games[games["temp"].notna()].sort_values("temp", ascending=False)
print(hot[["away_team", "home_team", "temp", "total"]].head(3).to_string(index=False))
# away_team home_team temp total
# NYG TB 88.0 30
# CIN TEN 84.0 71
# KC CHI 80.0 37
The notna() filter drops the 6 dome rows first, where temp was never recorded, then sorts the 16 outdoor rows. Note the two outdoor games at 84 and 88 degrees landed 71 and 30 combined points: temperature alone explains little, which is the point of pulling the columns next to each other. Across the 16 rows where temp exists, it runs from 60 to 88 degrees.
From the sample to the full pack
Every call above runs unchanged on the full 7,548-row games.csv, 1999 through 2026 (results through the 2025 season, plus 272 scheduled 2026 rows). Same 46 columns, same dtypes, bigger frames. The odds columns empty in this 1999 sample fill in from 2006 on. The pack also includes team-records-by-season.csv (861 rows, covered in the team-records CSV guide) and season-summaries.csv (27 rows), plus a data dictionary and SHA-256 checksums. Not sure raw nflverse downloads vs the preprocessed pack? The nflverse vs pack comparison lays out both routes. Need this week's scores over HTTP instead of files? The NFL data API examples run requests against live endpoints.
Not ready for 7,548 rows? season-summaries.csv is a complete table, free, 27 rows, one per season with scoring averages, home win rates, and favorite cover rates. It loads with the same read_csv call.
Checkout and download run through Getly. The full pack is 3 CSVs (7,548 + 861 + 27 rows), data dictionary, source SHA-256 checksums. The sample and season-summaries download free here, no signup.
NFL data in Python questions
- Does the NFL sample CSV load in pandas without any cleaning?
- Yes.
pd.read_csvon the sample URL returns a DataFrame with shape (22, 46), one row per game.game_idarrives as a string,gamedayparses as text you can convert withpd.to_datetime, and scores, lines, rest days, and roof read in with the right types on the first pass. The one thing to expect is NaN values intempandwindfor the 6 dome games, where the source file is blank. - Why do the temp and wind columns come in as floats with missing values?
- Blank cells in the CSV become NaN, and any integer column that contains NaN gets stored as float64. That is the honest reading: the 6 dome games in the sample have no temp or wind because the stadium roof was closed, so the number was never recorded. Keep them as NaN and the groupby and mean calls stay correct, or fill them only when the filling makes sense for your analysis.
- Will the same pandas code run on the full 7,548-row NFL pack?
- Yes, unchanged. The sample is the first 22 rows of games.csv with the same 46-column schema, so every read_csv, groupby, and sort_values call here runs the same way on the full file, 1999 through 2026. Only the row count grows, and the odds columns that sit empty in the 1999 sample fill in from 2006 onward. The full pack ships with a data dictionary and SHA-256 checksums.
Source and license
All game rows come from the nflverse-data project, file schedules/games.csv, downloaded 2026-09-06 with the SHA-256 recorded in the pack. nflverse-data is released under CC BY 4.0; credit it as "Data from nflverse, CC BY 4.0". Samples on this site carry the same license. No logos or league marks appear anywhere in the pack; team names are factual data. This page and the pack describe data only and offer no betting advice, picks, or predictions.