NBA Pythagorean Wins in Python
Pythagorean Wins
The 2021-2022 NBA season is approximately at the midpoint of the 82 game regular season with every team having played half or more of their games. Pythagorean wins is a metric to evaluate a team's win-loss record relative to expectations thus far. Points scored and points allowed by an NBA team, as well as their record for comparison, is the only statistical data needed for the calculation.
The calculation formula is simple. Points scored to the nth power divided by the sum of points scored to the nth power + points against to the nth power. The original expectation formula devised by Bill James uses a squared exponent to estimate the percentage of games a baseball team "should" have won based on their number of runs scored and allowed.
Daryl Morey is credited with being the first to adopt the formula to basketball replacing the squared exponent with 13.91. John Hollinger also applied the metric to basketball using the exponent 16.5. Alternatively, NBAstuffer uses 16.5 in their formula, but we'll stick to the traditional exponent values from Morey and Hollinger.
Rather than using scratch paper and a calculator, Python can be used to programmatically determine Pythagorean wins. Using sports data is how I first started learning Python. Find an interesting data set and experiment.
Team Calculation
I know I just said we'll use Python, but before jumping into the code, let's walk through a basic example step-by-step. The formula shouldn't feel too intimidating even if your math skills are rusty.
Points Scored n / ( Points Scored n + Points Allowed n )
The formula can be shortened even further by substituting in variables where A
represents Points Scored and B
represents Points Allowed (n
represents the exponent of either 13.91 or 16.5 from Morey and Hollinger respectively):
Step 1: A = Points Scored to the nth power
Step 2: B = Points Allowed to the nth power
Step 3: Pythagorean Wins = A / (A + B)
Plugging in real data will illuminate the simplicity. The Phoenix Suns are currently the league leader by record at 32-9 (as of this writing the morning of January 15, 2022). They have scored 4583 points and allowed 4284 points from the opponent. The formula can be written as follows using the 13.91 exponent from Daryl Morey.
Step 1: A = 4583 ^ 13.91
Step 2: B = 4284 ^ 13.91
Step 3: Result = A / (A + b)
Pythagorean Win Rate: 0.719
With John's Hollinger exponent of 15 the Pythagorean win rate is 0.733 or 73.3% for the Phoenix Suns. Through 41 games that translates to an approximate expected win total of either 29 (Morey) or 30 (Hollinger). Meaning the Suns are winning at a rate slightly above expectations given their points scored and points allowed.
Pythagorean wins should only be treated as a back-of-the-envelope type of proxy for evaluating a team's performance relative to expectations. Next, we can construct the Python implementation to compute Pythagorean wins.
Live Example
The Python program is broken into five separate functions (refer back to the hello world tutorial if you are new to Python). run_example
is the main function defining the primary data inputs and calls compute_pythagorean_wins
for the data calculation and output.
compute_pythagorean_wins
is performing three logical responsibilities, which could be separated into multiple single responsibility functions (leaving as one function for clarity). Calculating Pythagorean win rate, expected wins, and displaying the output summary. Within this function, three calculation or helper functions are also used, including calculate_win_rate
, calculate_expected_wins
, and extract_team_wins_losses
.
Step through the code line-by-line to understand each action and purpose. Experiment with the code by applying different values on lines 2-5 for the team name, team record, points scored, and points allowed. Additionally, below the code editor contains a list of data for all 32 NBA teams that you can reference.
This Python example for Pythagorean wins only scratches the surface of the basketball analytics and other calculations that can be accomplished in Python with relative ease once you get the hang of it.
NBA data as of January 15, 2022 prior to any games placed. Sourced from Basketball Reference.eriment with the example by plugging in different values on lines 2-5 for the team name, record, points scored, and points allowed. The table below is a current list of data for all 32 NBA teams at the time of this writing.
TM RECORD POINTS ALLOWED
ATL 17-24 4531 4586
BKN 21-22 4625 4554
BOS 26-15 4573 4477
CHA 23-20 4941 4966
CHI 27-13 4445 4343
CLE 25-18 4621 4403
DAL 23-19 4428 4326
DEN 21-19 4257 4228
DET 10-31 4152 4539
GSW 31-11 4627 4266
HOU 12-32 4755 5138
IND 15-28 4616 4654
LAC 21-22 4487 4535
LAL 21-21 4708 4738
MEM 30-15 5024 4858
MIA 27-15 4576 4376
MIL 27-17 4926 4745
MIN 20-22 4617 4592
NOP 16-26 4447 4620
NYK 21-21 4380 4391
OKC 14-27 4131 4416
ORL 8-35 4390 4768
PHI 24-17 4401 4326
PHX 32-9 4583 4284
POR 16-25 4459 4640
SAC 18-27 4935 5113
SAS 15-27 4653 4678
TOR 20-19 4184 4148
UTA 28-14 4835 4519
WAS 22-20 4527 4607