NBA Pythagorean Wins in Python

Calculate the Pythagorean expected wins of NBA teams using 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.

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