Skip to main content

Overview

Tracking data captures player movement and basketball actions through NBA’s SportVU camera system. This includes drives to the basket, touches and time of possession, passing metrics, speed and distance traveled, and hustle statistics like deflections and loose balls recovered.

Data Files

Drives

Drive metrics (penetration, scoring, passing)
  • drives.csv

Touches/Possessions

Ball touches and time of possession
  • possessions.csv (renamed from Possessions endpoint)

Passing

Passing and assist creation metrics
  • passing.csv / passing_ps.csv

Hustle Stats

Deflections, loose balls, charges, screens, box outs
  • hustle.csv / hustle_ps.csv

Speed & Distance

Miles run, average speed (included in hustle.csv)

Paint/Elbow/Post Touches

Touches in specific court areas
  • paint.csv, elbow.csv, post.csv

Schema: Drives

File: drives.csv
Generated by: new_tracking.py
Records: ~35,000+ player-season records
Source: NBA.com tracking API (PtMeasureType=Drives)

Fields

PLAYER_ID
integer
required
NBA.com player ID
PLAYER_NAME
string
required
Player name
TEAM_ID
integer
Team ID
TEAM_ABBREVIATION
string
Team abbreviation
Season
string
Season format: “2023-24”

Sample Data

PLAYER_ID,PLAYER_NAME,TEAM_ID,TEAM_ABBREVIATION,GP,W,L,MIN,DRIVES,DRIVE_FGM,DRIVE_FGA,DRIVE_FG_PCT,DRIVE_FTM,DRIVE_FTA,DRIVE_FT_PCT,DRIVE_PTS,DRIVE_PTS_PCT,DRIVE_PASSES,DRIVE_PASSES_PCT,DRIVE_AST,DRIVE_AST_PCT,DRIVE_TOV,DRIVE_TOV_PCT,DRIVE_PF,DRIVE_PF_PCT,Season
201985,AJ Price,1610612739,CLE,26,11,15,324.0,101,18,37,0.486,5,8,0.625,42,0.416,44,0.436,9,0.089,6,0.059,4,0.04,2014-15
201166,Aaron Brooks,1610612741,CHI,82,50,32,1885.0,854,165,355,0.465,63,76,0.829,400,0.468,309,0.362,76,0.089,59,0.069,40,0.047,2014-15

Schema: Touches & Possessions

File: possessions.csv (tracking/touches.csv in raw folders)
Generated by: new_tracking.py
Source: NBA.com tracking API (PtMeasureType=Possessions)
TOUCHES
integer
Total ball touches
FRONT_CT_TOUCHES
integer
Touches in frontcourt
TIME_OF_POSS
float
Total time of possession (minutes)
AVG_SEC_PER_TOUCH
float
Average seconds per touch
AVG_DRIB_PER_TOUCH
float
Average dribbles per touch
PTS_PER_TOUCH
float
Points scored per touch

Schema: Passing

File: passing.csv / passing_ps.csv
Generated by: passing.py + new_tracking.py
Records: ~100,000+ player-season records
Source: pbpstats.com API + NBA.com
nba_id
integer
NBA player ID
Name
string
Player name
Passes
integer
Total passes made
PASSES_RECEIVED
integer
Total passes received
POTENTIAL_AST
integer
Potential assists (passes leading to shot attempts)
Assists
integer
Actual assists
PotAss/Passes
float
Potential assist rate
AST_TO_PASS_PCT
float
Assist to pass percentage
AST_PTS_CREATED
integer
Points created via assists
Assist PPP
float
Points per possession on assists
High Value Assist %
float
Percentage of assists leading to high-value shots
ThreePtAssists
integer
Three-point assists
AtRimAssists
integer
Assists at rim
BadPassTurnovers
integer
Turnovers from bad passes

Schema: Hustle Stats

File: hustle.csv / hustle_ps.csv
Generated by: hustle.py
Source: NBA.com hustle stats + speed/distance tracking

Hustle Metrics

DEFLECTIONS
integer
Ball deflections
CHARGES_DRAWN
integer
Offensive fouls drawn
CONTESTED_SHOTS
integer
Total shots contested
CONTESTED_SHOTS_2PT
integer
Two-point shots contested
CONTESTED_SHOTS_3PT
integer
Three-point shots contested

Sample Data

PLAYER_ID,PLAYER_NAME,TEAM_ID,TEAM_ABBREVIATION,AGE,G,CONTESTED_SHOTS,CONTESTED_SHOTS_2PT,CONTESTED_SHOTS_3PT,DEFLECTIONS,CHARGES_DRAWN,SCREEN_ASSISTS,SCREEN_AST_PTS,OFF_LOOSE_BALLS_RECOVERED,DEF_LOOSE_BALLS_RECOVERED,LOOSE_BALLS_RECOVERED,PCT_LOOSE_BALLS_RECOVERED_OFF,PCT_LOOSE_BALLS_RECOVERED_DEF,OFF_BOXOUTS,DEF_BOXOUTS,BOX_OUT_PLAYER_TEAM_REBS,BOX_OUT_PLAYER_REBS,BOX_OUTS,PCT_BOX_OUTS_OFF,PCT_BOX_OUTS_DEF,PCT_BOX_OUTS_TEAM_REB,PCT_BOX_OUTS_REB,GP,W,L,MIN,DIST_FEET,DIST_MILES,DIST_MILES_OFF,DIST_MILES_DEF,AVG_SPEED,AVG_SPEED_OFF,AVG_SPEED_DEF,POSS,year
201166,Aaron Brooks,1610612750,MIN,33.0,32,49,19,30,10,1,1,2,4,3,7,0.571,0.429,0,6,3,1,6,0.0,1.0,0.75,0.25,32,19,13,189.0,71737.0,13.6,7.3,6.3,4.32,4.46,4.17,395,2018

Usage Examples

Elite Drivers Analysis

import pandas as pd

df = pd.read_csv('drives.csv')

# Extract year from Season
df['year'] = df['Season'].str.split('-').str[1].astype(int) + 2000

# 2024 high-volume drivers
elite_drivers = df[
    (df['year'] == 2024) & 
    (df['DRIVES'] >= 500)
].copy()

elite_drivers['PTS_PER_DRIVE'] = elite_drivers['DRIVE_PTS'] / elite_drivers['DRIVES']

print("Most Efficient High-Volume Drivers (2024):")
print(elite_drivers.sort_values('PTS_PER_DRIVE', ascending=False)[[
    'PLAYER_NAME', 'TEAM_ABBREVIATION', 'DRIVES', 'DRIVE_FG_PCT', 'PTS_PER_DRIVE'
]].head(20))

Playmaking on Drives

import pandas as pd

df = pd.read_csv('drives.csv')
df['year'] = df['Season'].str.split('-').str[1].astype(int) + 2000

# Find best drive playmakers
playmakers = df[
    (df['year'] == 2024) & 
    (df['DRIVES'] >= 300)
].copy()

playmakers['AST_PER_DRIVE'] = playmakers['DRIVE_AST'] / playmakers['DRIVES']

print("Top Drive Playmakers (2024):")
print(playmakers.sort_values('AST_PER_DRIVE', ascending=False)[[
    'PLAYER_NAME', 'DRIVES', 'DRIVE_AST', 'AST_PER_DRIVE', 'DRIVE_PASSES_PCT'
]].head(20))

Hustle Leaders

import pandas as pd

df = pd.read_csv('hustle.csv')

# 2024 hustle leaders
hustle_2024 = df[df['year'] == 2024]

print("Deflection Leaders:")
print(hustle_2024.nlargest(20, 'DEFLECTIONS')[['PLAYER_NAME', 'TEAM_ABBREVIATION', 'DEFLECTIONS', 'CONTESTED_SHOTS']])

print("\nLoose Ball Recovery Leaders:")
print(hustle_2024.nlargest(20, 'LOOSE_BALLS_RECOVERED')[['PLAYER_NAME', 'LOOSE_BALLS_RECOVERED', 'OFF_LOOSE_BALLS_RECOVERED', 'DEF_LOOSE_BALLS_RECOVERED']])

print("\nScreen Assist Leaders:")
print(hustle_2024.nlargest(20, 'SCREEN_ASSISTS')[['PLAYER_NAME', 'SCREEN_ASSISTS', 'SCREEN_AST_PTS']])

Distance & Speed Analysis

import pandas as pd

df = pd.read_csv('hustle.csv')

# 2024 miles run
df_2024 = df[df['year'] == 2024]

print("Most Distance Covered (2024):")
print(df_2024.nlargest(20, 'DIST_MILES')[['PLAYER_NAME', 'GP', 'DIST_MILES', 'AVG_SPEED']])

# Miles per game
df_2024['MPG'] = df_2024['DIST_MILES'] / df_2024['GP']
print("\nMost Miles Per Game:")
print(df_2024.nlargest(20, 'MPG')[['PLAYER_NAME', 'MPG', 'AVG_SPEED']])

Passing Creativity

import pandas as pd

df = pd.read_csv('passing.csv')

# 2024 creative passers
passers = df[
    (df['year'] == 2024) & 
    (df['Assists'] >= 200)
].copy()

print("High-Value Assist Leaders:")
print(passers.nlargest(20, 'High Value Assist %')[[
    'Name', 'Assists', 'High Value Assist %', 'Assist PPP', 'ThreePtAssists', 'AtRimAssists'
]])

Data Collection Scripts

new_tracking.py

Scrapes NBA.com tracking API for drives, touches, passing, etc.

hustle.py

Collects hustle stats and speed/distance data

passing.py

Fetches passing metrics from pbpstats.com

Notes

  • Drives = Any touch where player dribbles penetrating toward basket
  • Screen Assists = Screens that directly lead to made field goals
  • Contested Shots = Shots where player is closest defender within 3.5 feet
  • Speed measured in miles per hour (mph)
  • Distance in both feet and miles
SportVU tracking data only available from 2013-14 season onward. Earlier seasons lack tracking metrics.
Combine hustle stats with defensive metrics for complete defensive profiles. High deflections + low DFG% = elite defender.

Build docs developers (and LLMs) love