Lebron James vs. Michael Jordan: A Comparison of Two Legends

Aditya Garg, Sachin Vishwanathan, Sami Siddiqui
Data Bootcamp
Fall 2016

Abstract

Our project will attempt to solve the age-old debate of whether Lebron James or Michael Jordan was the superior basketball player. We attempt to look at both traditional and advanced statistics to take our crack at answering this question. We look at the players’ respective Player Efficiency Ratings as well as their Win Shares, both offensive and defensive (and total). We will go into further detail below about these advanced statistics as well as our efforts to account for the fact that Jordan and James played in different eras, and thus played against very different competition. Based on our analysis, it seems that Michael Jordan was the better player though the HHI and our own qualitative research suggests that there may be other factors also at play affecting our results.

Background

Michael Jordan

Michael Jordan took basketball to heights it had never previously reached, especially on the global scale. Jordan was famously cut from his high school’s varsity basketball team his sophomore year but used the snub as motivation to go on to become one of the greatest basketball players of all time. He played college basketball at UNC-Chapel Hill before being drafted in 1984 as the third overall pick by the Chicago Bulls. Jordan went on to become a 14-time all star, 5-time NBA regular season MVP and 6-time NBA Champion and Finals MVP. Despite this greatness, his success did not come without struggles; he missed almost his entire second season due to a broken foot, he retired (at the time) and played minor league baseball during parts of the 1993-1994 and 1994-1995 seasons. He again “retired” after the 1998 NBA Finals only to come back for the 2001-2002 season and officially retired for good after 2002-2003. He is often regarded as the Greatest of All Time because of his dominance on the court as well as in off-court ventures, but we needn’t get into that for the purpose of our project.

Lebron James

Lebron James was drafted straight out of St. Vincent-St. Mary’s High School in 2003 as the first overall draft pick by the Cleveland Cavaliers, his hometown team. Lebron went on to lead the Cavaliers to the NBA Finals in 2007 almost singlehandedly, where they fell to the San Antonio Spurs in four games. James failed to win a championship with the Cavaliers and left for the Miami Heat in 2010, where he spent four years. He led the Heat to the NBA Finals each year he spent in Miami, winning two championships and two Finals MVP awards along the way. He returned to Cleveland and led the Cavaliers to another NBA Finals appearance before falling to the Golden State Warriors. This past season he was able to lead the Cavaliers to their first NBA Title, capturing another NBA Finals MVP award along the way. Though Lebron still has a lot of his career remaining, he has most certainly reached his peak, accumulating an impressive twelve (and still counting) all star appearances, four regular season MVPs, and three Finals MVPs. Lebron has been widely regarded as the best basketball player since Jordan, but our project will aim to answer the question of whether he was actually better than Jordan as a lot of his fans claim.

Comparing Both Players

The data we looked at covered 13 seasons for both players. For Lebron James we looked at the time period from 2003-2016 while for Michael Jordan we looked at the period from 1984-2003. It is important to note that we excluded the following years for Jordan: 1985-86, 1993-94, 1994-95, 1998-2001 because Jordan was either injured or did not play that season (was retired). To read the data, we first saved it as a CSV file for both players and then imported it into Jupyter. The specific code we used to call this information included:


In [2]:
import sys                             # system module
import pandas as pd                    # data package
import matplotlib.pyplot as plt        # graphics module  
import datetime as dt                  # date and time module
import numpy as np                     # foundation for Pandas
import seaborn.apionly as sns          # fancy matplotlib graphics (no styling)
from pandas_datareader import wb, data as web  # worldbank data

# plotly imports
from plotly.offline import iplot, iplot_mpl  # plotting functions
import plotly.graph_objs as go               
import plotly                                # just to print version and init notebook
import cufflinks as cf                       # gives us df.iplot that feels like df.plot
cf.set_config_file(offline=True, offline_show_link=False)

# these lines make our graphics show up in the notebook
%matplotlib inline             
plotly.offline.init_notebook_mode(connected=True)

# check versions 
print('Python version:', sys.version)
print('Pandas version: ', pd.__version__)
print('Plotly version: ', plotly.__version__)
print('Today: ', dt.date.today())

path = 'data/Jordan_Per_Game.xlsx'
df_J_I = pd.read_excel(path)

path_1 = 'data/Jordan_Advanced.xlsx'
df_J_A = pd.read_excel(path_1)

path_2 = 'data/Lebron_Per_Game.xlsx'
df_L_I = pd.read_excel(path_2)

path_3 = 'data/Lebron_Advanced_Stats.xlsx'
df_L_A = pd.read_excel(path_3)


Python version: 3.5.2 |Anaconda 4.2.0 (x86_64)| (default, Jul  2 2016, 17:52:12) 
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.28)]
Pandas version:  0.19.0
Plotly version:  1.12.11
Today:  2016-12-22

Jordan Statistics

The data shown below are Michael Jordan's "traditional" career statistics for the years we are looking at for the purposes of this project. This excludes much of the advanced analytics we more seriously weigh for our project, but we include them because all advanced statistics are based off these more basic stats to some degree. Looking further below, we start to delve deeper by looking at the more advanced statistics as well, such as Win Shares and VORP. We provide the same data for James looking at his thirteen seasons in the league so far.


In [3]:
df_J_I #Jordan's traditional statistics


Out[3]:
Season Age Tm Lg Pos G GS MP FG FGA ... FT% ORB DRB TRB AST STL BLK TOV PF PTS
0 1984-85 21 CHI NBA SG 82 82 38.3 10.2 19.8 ... 0.845 2.0 4.5 6.5 5.9 2.4 0.8 3.5 3.5 28.2
1 1986-87 23 CHI NBA SG 82 82 40.0 13.4 27.8 ... 0.857 2.0 3.2 5.2 4.6 2.9 1.5 3.3 2.9 37.1
2 1987-88 24 CHI NBA SG 82 82 40.4 13.0 24.4 ... 0.841 1.7 3.8 5.5 5.9 3.2 1.6 3.1 3.3 35.0
3 1988-89 25 CHI NBA SG 81 81 40.2 11.9 22.2 ... 0.850 1.8 6.2 8.0 8.0 2.9 0.8 3.6 3.0 32.5
4 1989-90 26 CHI NBA SG 82 82 39.0 12.6 24.0 ... 0.848 1.7 5.1 6.9 6.3 2.8 0.7 3.0 2.9 33.6
5 1990-91 27 CHI NBA SG 82 82 37.0 12.1 22.4 ... 0.851 1.4 4.6 6.0 5.5 2.7 1.0 2.5 2.8 31.5
6 1991-92 28 CHI NBA SG 80 80 38.8 11.8 22.7 ... 0.832 1.1 5.3 6.4 6.1 2.3 0.9 2.5 2.5 30.1
7 1992-93 29 CHI NBA SG 78 78 39.3 12.7 25.7 ... 0.837 1.7 5.0 6.7 5.5 2.8 0.8 2.7 2.4 32.6
8 1995-96 32 CHI NBA SG 82 82 37.7 11.2 22.6 ... 0.834 1.8 4.8 6.6 4.3 2.2 0.5 2.4 2.4 30.4
9 1996-97 33 CHI NBA SG 82 82 37.9 11.2 23.1 ... 0.833 1.4 4.5 5.9 4.3 1.7 0.5 2.0 1.9 29.6
10 1997-98 34 CHI NBA SG 82 82 38.8 10.7 23.1 ... 0.784 1.6 4.2 5.8 3.5 1.7 0.5 2.3 1.8 28.7
11 2001-02 38 WAS NBA SF 60 53 34.9 9.2 22.1 ... 0.790 0.8 4.8 5.7 5.2 1.4 0.4 2.7 2.0 22.9
12 2002-03 39 WAS NBA SF 82 67 37.0 8.3 18.6 ... 0.821 0.9 5.2 6.1 3.8 1.5 0.5 2.1 2.1 20.0

13 rows × 30 columns


In [4]:
df_J_A #Jordan's advanced statistics


Out[4]:
Season Age Tm Lg Pos G MP PER TS% 3PAr ... TOV% USG% OWS DWS WS WS/48 OBPM DBPM BPM VORP
0 1984-85 21 CHI NBA SG 82 3144 25.8 0.592 0.032 ... 13.0 29.8 10.3 3.7 14.0 0.213 6.8 1.4 8.2 8.1
1 1986-87 23 CHI NBA SG 82 3281 29.8 0.562 0.029 ... 9.1 38.3 11.9 5.0 16.9 0.247 8.0 0.6 8.6 8.8
2 1987-88 24 CHI NBA SG 82 3311 31.7 0.603 0.027 ... 9.6 34.1 15.2 6.1 21.2 0.308 9.8 2.3 12.2 11.8
3 1988-89 25 CHI NBA SG 81 3255 31.1 0.614 0.055 ... 11.9 32.1 14.6 5.2 19.8 0.292 9.8 2.7 12.6 12.0
4 1989-90 26 CHI NBA SG 82 3197 31.2 0.606 0.125 ... 9.8 33.7 14.7 4.3 19.0 0.285 9.7 0.8 10.6 10.1
5 1990-91 27 CHI NBA SG 82 3034 31.6 0.605 0.051 ... 8.7 32.9 14.9 5.4 20.3 0.321 8.9 1.8 10.8 9.8
6 1991-92 28 CHI NBA SG 80 3102 27.7 0.579 0.055 ... 8.8 31.7 12.1 5.6 17.7 0.274 6.9 1.7 8.6 8.3
7 1992-93 29 CHI NBA SG 78 3067 29.7 0.564 0.115 ... 8.4 34.7 12.0 5.2 17.2 0.270 8.3 1.2 9.5 8.9
8 1995-96 32 CHI NBA SG 82 3090 29.4 0.582 0.141 ... 8.4 33.3 14.2 6.2 20.4 0.317 7.2 1.4 8.6 8.3
9 1996-97 33 CHI NBA SG 82 3106 27.8 0.567 0.157 ... 7.2 33.2 13.3 5.0 18.3 0.283 6.5 0.2 6.7 6.8
10 1997-98 34 CHI NBA SG 82 3181 25.2 0.533 0.067 ... 7.7 33.7 10.4 5.4 15.8 0.238 4.6 0.0 4.6 5.3
11 2001-02 38 WAS NBA SF 60 2093 20.7 0.468 0.040 ... 9.9 36.0 1.2 2.1 3.3 0.075 2.3 0.1 2.5 2.4
12 2002-03 39 WAS NBA SF 82 3031 19.3 0.491 0.036 ... 9.4 28.7 2.9 3.4 6.2 0.099 0.9 0.1 1.0 2.3

13 rows × 27 columns

James Statistics


In [5]:
df_L_I #James traditional statistics


Out[5]:
Season Age Tm Lg Pos G GS MP FG FGA ... FT% ORB DRB TRB AST STL BLK TOV PF PTS
0 2003-04 19 CLE NBA SG 79 79 39.5 7.9 18.9 ... 0.754 1.3 4.2 5.5 5.9 1.6 0.7 3.5 1.9 20.9
1 2004-05 20 CLE NBA SF 80 80 42.4 9.9 21.1 ... 0.750 1.4 6.0 7.4 7.2 2.2 0.7 3.3 1.8 27.2
2 2005-06 21 CLE NBA SF 79 79 42.5 11.1 23.1 ... 0.738 0.9 6.1 7.0 6.6 1.6 0.8 3.3 2.3 31.4
3 2006-07 22 CLE NBA SF 78 78 40.9 9.9 20.8 ... 0.698 1.1 5.7 6.7 6.0 1.6 0.7 3.2 2.2 27.3
4 2007-08 23 CLE NBA SF 75 74 40.4 10.6 21.9 ... 0.712 1.8 6.1 7.9 7.2 1.8 1.1 3.4 2.2 30.0
5 2008-09 24 CLE NBA SF 81 81 37.7 9.7 19.9 ... 0.780 1.3 6.3 7.6 7.2 1.7 1.1 3.0 1.7 28.4
6 2009-10 25 CLE NBA SF 76 76 39.0 10.1 20.1 ... 0.767 0.9 6.4 7.3 8.6 1.6 1.0 3.4 1.6 29.7
7 2010-11 26 MIA NBA SF 79 79 38.8 9.6 18.8 ... 0.759 1.0 6.5 7.5 7.0 1.6 0.6 3.6 2.1 26.7
8 2011-12 27 MIA NBA SF 62 62 37.5 10.0 18.9 ... 0.771 1.5 6.4 7.9 6.2 1.9 0.8 3.4 1.5 27.1
9 2012-13 28 MIA NBA PF 76 76 37.9 10.1 17.8 ... 0.753 1.3 6.8 8.0 7.3 1.7 0.9 3.0 1.4 26.8
10 2013-14 29 MIA NBA PF 77 77 37.7 10.0 17.6 ... 0.750 1.1 5.9 6.9 6.3 1.6 0.3 3.5 1.6 27.1
11 2014-15 30 CLE NBA SF 69 69 36.1 9.0 18.5 ... 0.710 0.7 5.3 6.0 7.4 1.6 0.7 3.9 2.0 25.3
12 2015-16 31 CLE NBA SF 76 76 35.6 9.7 18.6 ... 0.731 1.5 6.0 7.4 6.8 1.4 0.6 3.3 1.9 25.3

13 rows × 30 columns


In [6]:
df_L_A #James advanced statistics


Out[6]:
Season Age Tm Lg Pos G MP PER TS% 3PAr ... TOV% USG% OWS DWS WS WS/48 OBPM DBPM BPM VORP
0 2003-04 19 CLE NBA SG 79 3122 18.3 0.488 0.145 ... 13.9 28.2 2.4 2.6 5.1 0.078 2.2 -0.2 1.9 3.1
1 2004-05 20 CLE NBA SF 80 3388 25.7 0.554 0.183 ... 11.8 29.7 9.7 4.6 14.3 0.203 6.9 1.5 8.3 8.8
2 2005-06 21 CLE NBA SF 79 3361 28.1 0.568 0.208 ... 10.7 33.6 12.0 4.3 16.3 0.232 7.9 1.4 9.3 9.5
3 2006-07 22 CLE NBA SF 78 3190 24.5 0.552 0.191 ... 11.5 31.0 8.0 5.7 13.7 0.206 5.4 2.0 7.4 7.6
4 2007-08 23 CLE NBA SF 75 3027 29.1 0.568 0.219 ... 11.4 33.5 10.7 4.6 15.2 0.242 9.0 2.3 11.2 10.1
5 2008-09 24 CLE NBA SF 81 3054 31.7 0.591 0.238 ... 11.0 33.8 13.7 6.5 20.3 0.318 9.4 3.6 13.0 11.6
6 2009-10 25 CLE NBA SF 76 2966 31.1 0.604 0.253 ... 12.3 33.5 13.3 5.2 18.5 0.299 9.7 2.8 12.5 10.9
7 2010-11 26 MIA NBA SF 79 3063 27.3 0.594 0.188 ... 13.8 31.5 10.3 5.3 15.6 0.244 6.5 2.1 8.6 8.2
8 2011-12 27 MIA NBA SF 62 2326 30.7 0.605 0.127 ... 13.3 32.0 10.0 4.5 14.5 0.298 8.3 2.7 11.0 7.6
9 2012-13 28 MIA NBA PF 76 2877 31.6 0.640 0.188 ... 12.4 30.2 14.6 4.7 19.3 0.322 9.2 2.4 11.6 9.8
10 2013-14 29 MIA NBA PF 77 2902 29.3 0.649 0.226 ... 14.4 31.0 12.3 3.7 15.9 0.264 8.0 0.9 8.9 8.0
11 2014-15 30 CLE NBA SF 69 2493 25.9 0.577 0.265 ... 15.3 32.3 7.4 2.9 10.4 0.199 6.2 1.2 7.4 5.9
12 2015-16 31 CLE NBA SF 76 2709 27.5 0.588 0.199 ... 13.2 31.4 9.6 4.0 13.6 0.242 6.9 2.3 9.1 7.6

13 rows × 27 columns

Performance Efficiency Rating

The Performance Efficieny Rating (PER) aims to provide a comprehensive measure of every possible contribution a player can make on a basketball court (shown in the formula below) and simplify the statistic into one number.

Over the years, many fans have attempted to create an impartial formula of statistics to compare various legends from different eras, but the most thorough may be ESPN’s greatest solution of creating an online competition for sports fans: Fantasy Basketball. The current formula used to score each individual per game incorporates various personal statistics such as points scored, blocks, steals, assists, rebounds, turnovers, field goals, and free throws. Using historical data accumulated on the links above, we can create a similar equation to make various comparisons between full careers, performance on different teams throughout careers, and solely starting seasons, among others.

Formula: Score = Points + Blocks + Steals + Assists + Rebounds + Turnovers + Field Goals Made - Field Goals Attempted + Free Throws Made - Free Throws Attempted


In [7]:
#Calculating PER using above formula for Michael Jordan 
df_J_I['PER'] = (df_J_I['PTS'] + df_J_I['BLK'] + df_J_I['STL'] + df_J_I['AST'] + df_J_I['TRB'] + df_J_I['FG'] 
                 + df_J_I['FT'] - df_J_I['TOV'] - df_J_I['FGA'] - df_J_I['FTA']) 
df_J_I


Out[7]:
Season Age Tm Lg Pos G GS MP FG FGA ... ORB DRB TRB AST STL BLK TOV PF PTS PER
0 1984-85 21 CHI NBA SG 82 82 38.3 10.2 19.8 ... 2.0 4.5 6.5 5.9 2.4 0.8 3.5 3.5 28.2 29.3
1 1986-87 23 CHI NBA SG 82 82 40.0 13.4 27.8 ... 2.0 3.2 5.2 4.6 2.9 1.5 3.3 2.9 37.1 31.9
2 1987-88 24 CHI NBA SG 82 82 40.4 13.0 24.4 ... 1.7 3.8 5.5 5.9 3.2 1.6 3.1 3.3 35.0 35.0
3 1988-89 25 CHI NBA SG 81 81 40.2 11.9 22.2 ... 1.8 6.2 8.0 8.0 2.9 0.8 3.6 3.0 32.5 36.8
4 1989-90 26 CHI NBA SG 82 82 39.0 12.6 24.0 ... 1.7 5.1 6.9 6.3 2.8 0.7 3.0 2.9 33.6 34.6
5 1990-91 27 CHI NBA SG 82 82 37.0 12.1 22.4 ... 1.4 4.6 6.0 5.5 2.7 1.0 2.5 2.8 31.5 32.7
6 1991-92 28 CHI NBA SG 80 80 38.8 11.8 22.7 ... 1.1 5.3 6.4 6.1 2.3 0.9 2.5 2.5 30.1 31.1
7 1992-93 29 CHI NBA SG 78 78 39.3 12.7 25.7 ... 1.7 5.0 6.7 5.5 2.8 0.8 2.7 2.4 32.6 31.5
8 1995-96 32 CHI NBA SG 82 82 37.7 11.2 22.6 ... 1.8 4.8 6.6 4.3 2.2 0.5 2.4 2.4 30.4 28.9
9 1996-97 33 CHI NBA SG 82 82 37.9 11.2 23.1 ... 1.4 4.5 5.9 4.3 1.7 0.5 2.0 1.9 29.6 27.0
10 1997-98 34 CHI NBA SG 82 82 38.8 10.7 23.1 ... 1.6 4.2 5.8 3.5 1.7 0.5 2.3 1.8 28.7 23.6
11 2001-02 38 WAS NBA SF 60 53 34.9 9.2 22.1 ... 0.8 4.8 5.7 5.2 1.4 0.4 2.7 2.0 22.9 18.8
12 2002-03 39 WAS NBA SF 82 67 37.0 8.3 18.6 ... 0.9 5.2 6.1 3.8 1.5 0.5 2.1 2.1 20.0 18.7

13 rows × 31 columns


In [8]:
#Calculating PER using above formula for Lebron James 
df_L_I['PER'] = (df_L_I['PTS'] + df_L_I['BLK'] + df_L_I['STL'] + df_L_I['AST'] + df_L_I['TRB'] 
                 + df_L_I['FG'] + df_L_I['FT'] - df_L_I['TOV'] - df_L_I['FGA'] - df_L_I['FTA'])
df_L_I


Out[8]:
Season Age Tm Lg Pos G GS MP FG FGA ... ORB DRB TRB AST STL BLK TOV PF PTS PER
0 2003-04 19 CLE NBA SG 79 79 39.5 7.9 18.9 ... 1.3 4.2 5.5 5.9 1.6 0.7 3.5 1.9 20.9 18.7
1 2004-05 20 CLE NBA SF 80 80 42.4 9.9 21.1 ... 1.4 6.0 7.4 7.2 2.2 0.7 3.3 1.8 27.2 28.2
2 2005-06 21 CLE NBA SF 79 79 42.5 11.1 23.1 ... 0.9 6.1 7.0 6.6 1.6 0.8 3.3 2.3 31.4 29.4
3 2006-07 22 CLE NBA SF 78 78 40.9 9.9 20.8 ... 1.1 5.7 6.7 6.0 1.6 0.7 3.2 2.2 27.3 25.5
4 2007-08 23 CLE NBA SF 75 74 40.4 10.6 21.9 ... 1.8 6.1 7.9 7.2 1.8 1.1 3.4 2.2 30.0 30.3
5 2008-09 24 CLE NBA SF 81 81 37.7 9.7 19.9 ... 1.3 6.3 7.6 7.2 1.7 1.1 3.0 1.7 28.4 30.7
6 2009-10 25 CLE NBA SF 76 76 39.0 10.1 20.1 ... 0.9 6.4 7.3 8.6 1.6 1.0 3.4 1.6 29.7 32.4
7 2010-11 26 MIA NBA SF 79 79 38.8 9.6 18.8 ... 1.0 6.5 7.5 7.0 1.6 0.6 3.6 2.1 26.7 28.6
8 2011-12 27 MIA NBA SF 62 62 37.5 10.0 18.9 ... 1.5 6.4 7.9 6.2 1.9 0.8 3.4 1.5 27.1 29.7
9 2012-13 28 MIA NBA PF 76 76 37.9 10.1 17.8 ... 1.3 6.8 8.0 7.3 1.7 0.9 3.0 1.4 26.8 32.3
10 2013-14 29 MIA NBA PF 77 77 37.7 10.0 17.6 ... 1.1 5.9 6.9 6.3 1.6 0.3 3.5 1.6 27.1 29.2
11 2014-15 30 CLE NBA SF 69 69 36.1 9.0 18.5 ... 0.7 5.3 6.0 7.4 1.6 0.7 3.9 2.0 25.3 25.3
12 2015-16 31 CLE NBA SF 76 76 35.6 9.7 18.6 ... 1.5 6.0 7.4 6.8 1.4 0.6 3.3 1.9 25.3 27.5

13 rows × 31 columns


In [9]:
#finding average PER for Lebron 
s = 0
c = 0
for i in range(13):
    s = s + df_L_I['PER'][i]
    c = c + 1
Lebron_avg_PER = s / c 

#finding average PER for Jordan 
s = 0
c = 0
for i in range(13):
    s = s + df_J_I['PER'][i]
    c = c + 1
Jordan_avg_PER = s / c

print("Jordan's Average PER is: ", round(Jordan_avg_PER,2))
print("Lebron's Average PER is: ", round(Lebron_avg_PER,2))



avg_PER = pd.DataFrame({'Name':['Lebron James', 'Michael Jordan'], 'Average PER':[Lebron_avg_PER, Jordan_avg_PER]})
avg_PER = avg_PER.set_index(['Name'])

fig, ax = plt.subplots()
plt.style.use('bmh')
avg_PER.plot(ax=ax, legend=False, kind = 'bar',color = ['blue','purple'], alpha = 0.65,rot = 0)
ax.set_xlabel("Players", fontsize = 14)
ax.set_ylabel('Average PER',fontsize = 14)
ax.set_title('Average PERs for Players', fontsize = 14)
ax.set_ylim(0,40)


Jordan's Average PER is:  29.22
Lebron's Average PER is:  28.29
Out[9]:
(0, 40)

As the above information shows, Michael Jordan had the higher PER, indicating a higher "efficieny" and better performance on average throughout the thirteen seasons.


In [10]:
#List of Lebron PER 
list_Lebron_PER = []
for i in range(13):
    list_Lebron_PER.append(df_L_I['PER'][i])

#List of Jordan PER
list_Jordan_PER = []
for i in range(13):
    list_Jordan_PER.append(df_J_I['PER'][i])

#x-axis values
list_Seasons = [Season for Season in range(1, 14)]

plt.plot(list_Seasons, list_Lebron_PER, label = "Lebron James")
plt.plot(list_Seasons, list_Jordan_PER, label = "Michael Jordan")
plt.xlabel("Season")
plt.ylabel("Performance Efficiency Rating")
plt.title("Comparing Performance Efficiency Ratings across Seasons")
plt.legend()
plt.show()


Even though Michael Jordan had the higher average PER throughout his career, Lebron James has had the more stable rating throughout his thirteen measured seasons. This can be attributed to a variety of factors, most notably the fact that we are excluding several of Jordan's seasons. Since Lebron was drafted out of high school, he began his NBA career four years earlier in life than Jordan. Additionally, Jordan "retiring" twice before actually ending his career resulted in hiatuses from the NBA for years at a time, meaning he was actually significantly older at the end of the period in his career we are looking at than Lebron currently is. Age, especially in the NBA, is an important factor to consider when analyzing individual statistics, particular one that is as holistic as the Player Efficiency Rating.

Offensive Win Share

Offensive Win Share (OWS) attempts to measure the amount of team wins that can be attributed to an individual player based on offensive output.


In [11]:
#Finding Lebron's average OWS
s = 0
c = 0
for i in range(13):
    s = s + df_L_A['OWS'][i]
    c = c + 1
Lebron_avg_OWS = s / c

#Finding Jordan's average OWS
d = 0
e = 0
for i in range(13):
    d = d + df_J_A['OWS'][i]
    e = e + 1
Jordan_avg_OWS = d / e

print("Jordan's Average OWS is: ", round(Jordan_avg_OWS, 2))
print("Lebron's Average OWS is: ", round(Lebron_avg_OWS, 2))

avg_OWS = pd.DataFrame({'Name':['Lebron James', 'Michael Jordan'], 'Average PER':[Lebron_avg_OWS, Jordan_avg_OWS]})
avg_OWS = avg_OWS.set_index(['Name'])


fig, ax = plt.subplots()
plt.style.use('bmh')
avg_OWS.plot(ax=ax, legend=False, kind = 'bar',color = ['blue','purple'], alpha = 0.65,rot = 0)
ax.set_xlabel("Players", fontsize = 14)
ax.set_ylabel('Average OWS',fontsize = 14)
ax.set_title('Average OWS for Players', fontsize = 14)
ax.set_ylim(0,15)


Jordan's Average OWS is:  11.36
Lebron's Average OWS is:  10.31
Out[11]:
(0, 15)

This would appear to indicate Jordan was the superior offensive player.


In [12]:
#List of Lebron OWS
list_Lebron_OWS = []
for i in range(13):
    list_Lebron_OWS.append(df_L_A['OWS'][i])

#List of Jordan OWS
list_Jordan_OWS = []
for i in range(13):
    list_Jordan_OWS.append(df_J_A['OWS'][i])

#x-axis values
list_Seasons = [Season for Season in range(1, 14)]

plt.plot(list_Seasons, list_Lebron_OWS, label = "Lebron James")
plt.plot(list_Seasons, list_Jordan_OWS, label = "Michael Jordan")
plt.xlabel("Season")
plt.ylabel("Offensive Win Shares")
plt.title("Comparing Offensive Win Shares across Seasons")
plt.legend()
plt.show()


As is the case above with PER, Jordan experiences a significant decline towards the tail end of his career for the reasons mentioned previously. There are periods of time where Lebron temproarily has a higher OWS, especially more recently, however Jordan, on average, appears to have been the superior offensive talent.

Defensive Win Share

This is similar to OWS, but instead looks at the individual's defensive statistics when looking at wins attributable to the player.


In [13]:
#Finding Lebron's average DWS
s = 0
c = 0
for i in range(13):
    s = s + df_L_A['DWS'][i]
    c = c + 1
Lebron_avg_DWS = s / c

#Finding Jordan's average DWS
g = 0
h = 0
for i in range(13):
    g = g + df_J_A['DWS'][i]
    h = h + 1
Jordan_avg_DWS = g / h

print("Jordan's Average DWS: ", round(Jordan_avg_DWS,2))
print("Lebron's Average DWS: ", round(Lebron_avg_DWS, 2))

avg_DWS = pd.DataFrame({'Name':['Lebron James', 'Michael Jordan'], 'Average PER':[Lebron_avg_DWS, Jordan_avg_DWS]})
avg_DWS = avg_DWS.set_index(['Name'])

fig, ax = plt.subplots()
plt.style.use('bmh')
avg_DWS.plot(ax=ax, legend=False, kind = 'bar',color = ['blue','purple'], alpha = 0.65,rot = 0)
ax.set_xlabel("Players", fontsize = 14)
ax.set_ylabel('Average DWS',fontsize = 14)
ax.set_title('Average DWS for Players', fontsize = 14)
ax.set_ylim(0,6)


Jordan's Average DWS:  4.82
Lebron's Average DWS:  4.51
Out[13]:
(0, 6)

Again, Jordan is the superior player in this statistic. This was a little more of a surprise as Lebron is known as much for his defense as he is for anything while Jordan was more prominent for his offensive prowess. The statistics here show Jordan to be the better defensive player, though statistics can be misleading (more on this below).


In [14]:
#List of Lebron DWS
list_Lebron_DWS = []
for i in range(13):
    list_Lebron_DWS.append(df_L_A['DWS'][i])

#List of Jordan DWS
list_Jordan_DWS = []
for i in range(13):
    list_Jordan_DWS.append(df_J_A['DWS'][i])

#x-axis values
list_Seasons = [Season for Season in range(1, 14)]

plt.plot(list_Seasons, list_Lebron_DWS, label = "Lebron James")
plt.plot(list_Seasons, list_Jordan_DWS, label = "Michael Jordan")
plt.xlabel("Season")
plt.ylabel("Defensive Win Shares")
plt.title("Comparing Defensive Win Shares across Seasons")
plt.legend()
plt.show()


The DWS for both players appear to trend along the same lines, though again there is a sharp drop for Jordan towards the end of his career.

Win Shares

This is the combined OWS and DWS, which looks at the number of wins directly attributable to the individual player.


In [15]:
#Finding Lebron Average WS
s = 0
c = 0
for i in range(13):
    s = s + df_L_A['WS'][i]
    c = c + 1
Lebron_avg_WS = s / c

#Finding Jordan Average WS
s = 0
c = 0
for i in range(13):
    s = s + df_J_A['WS'][i]
    c = c + 1
Jordan_avg_WS = s / c

print("Jordan's average WS is: ", round(Jordan_avg_WS,2))
print("James's average WS is: ", round(Lebron_avg_WS,2))


avg_WS = pd.DataFrame({'Name':['Lebron James', 'Michael Jordan'], 'Average PER':[Lebron_avg_WS, Jordan_avg_WS]})
avg_WS = avg_WS.set_index(['Name'])

fig, ax = plt.subplots()
plt.style.use('bmh')
avg_WS.plot(ax=ax, legend=False, kind = 'bar',color = ['blue','purple'], alpha = 0.65,rot = 0)
ax.set_xlabel("Players", fontsize = 14)
ax.set_ylabel('Average WS',fontsize = 14)
ax.set_title('Average WS for Players', fontsize = 14)
ax.set_ylim(0,18)


Jordan's average WS is:  16.16
James's average WS is:  14.82
Out[15]:
(0, 18)

As was expected based on the previous data of OWS and DWS, Jordan would appear to be responsible for an average of almost 1.5 wins more than Lebron, making him the superior player based off this.


In [16]:
#List of Lebron WS
list_Lebron_WS = []
for i in range(13):
    list_Lebron_WS.append(df_L_A['WS'][i])

#List of Jordan WS
list_Jordan_WS = []
for i in range(13):
    list_Jordan_WS.append(df_J_A['WS'][i])

#x-axis values
list_Seasons = [Season for Season in range(1, 14)]

plt.plot(list_Seasons, list_Lebron_WS, label = "Lebron James")
plt.plot(list_Seasons, list_Jordan_WS, label = "Michael Jordan")
plt.xlabel("Season")
plt.ylabel("Win Shares")
plt.title("Comparing Win Shares across Seasons")
plt.legend()
plt.show()


The data confirms the other statistis we computed earlier. As we look at the trend over time, we see that again they seem to follow along closely except for at the end of Jordan's career where we see a sharp drop.

Calculating HHI

HHI is traditionally used as a measure of market concentration. It can be applied in a sports context to try and estimate league parity -- how evenly talent is distributed across teams in a league.

Calculating HHI during Lebron James's playing years


In [17]:
path = 'data/NBA_Champions_Lebron.xlsx'
df_NBA_Champ_Lebron = pd.read_excel(path)
df_NBA_Champ_Lebron


Out[17]:
Year Champion Loser Games MVP Winning Coach East Finals Loser West Finals Loser
0 2016 Cleveland Cavaliers Golden State Warriors 2016-04-03 LeBron James Tyronn Lue Toronto Raptors Oklahoma City Thunder
1 2015 Golden State Warriors Cleveland Cavaliers 2016-04-02 Andre Iguodala Steve Kerr Atlanta Hawks Houston Rockets
2 2014 San Antonio Spurs Miami Heat 2016-04-01 Kawhi Leonard Gregg Popovich Indiana Pacers Oklahoma City Thunder
3 2013 Miami Heat San Antonio Spurs 2016-04-03 LeBron James Erik Spoelstra Indiana Pacers Memphis Grizzlies
4 2012 Miami Heat Oklahoma City Thunder 2016-04-01 LeBron James Erik Spoelstra Boston Celtics San Antonio Spurs
5 2011 Dallas Mavericks Miami Heat 2016-04-02 Dirk Nowitzki Rick Carlisle Chicago Bulls Oklahoma City Thunder
6 2010 Los Angeles Lakers Boston Celtics 2016-04-03 Kobe Bryant Phil Jackson Orlando Magic Phoenix Suns
7 2009 Los Angeles Lakers Orlando Magic 2016-04-01 Kobe Bryant Phil Jackson Cleveland Cavaliers Denver Nuggets
8 2008 Boston Celtics Los Angeles Lakers 2016-04-02 Paul Pierce Doc Rivers Detroit Pistons San Antonio Spurs
9 2007 San Antonio Spurs Cleveland Cavaliers 2000-04-01 Tony Parker Gregg Popovich Detroit Pistons Utah Jazz
10 2006 Miami Heat Dallas Mavericks 2016-04-02 Dwyane Wade Pat Riley Detroit Pistons Phoenix Suns
11 2005 San Antonio Spurs Detroit Pistons 2016-04-03 Tim Duncan Gregg Popovich Miami Heat Phoenix Suns
12 2004 Detroit Pistons Los Angeles Lakers 2016-04-01 Chauncey Billups Larry Brown Indiana Pacers Minnesota Timberwolves

In [18]:
dict_Lebron = {}

for i in range(13):
    if df_NBA_Champ_Lebron['Champion'][i] in dict_Lebron.keys(): #check and see if in dictionary -- if so, add one to value
        dict_Lebron[df_NBA_Champ_Lebron['Champion'][i]] = 1 + dict_Lebron.get(df_NBA_Champ_Lebron['Champion'][i]) 
    else: #if not in dictionary, add in dictionary
        dict_Lebron[df_NBA_Champ_Lebron['Champion'][i]] = 1

total_Lebron = 0 #calculating HHI
for i in dict_Lebron.values():
    total_Lebron = total_Lebron + i*i
HHI_Lebron = total_Lebron / 13

print("The HHI during the years Lebron played is: ", round(HHI_Lebron, 2))


The HHI during the years Lebron played is:  2.08

Calculating HHI during Michael Jordan's playing years


In [19]:
path = 'data/NBA_Champions_Jordan.xlsx'
df_NBA_Champ_Jordan = pd.read_excel(path)
df_NBA_Champ_Jordan


Out[19]:
Year Champion Loser Games MVP Winning Coach East Finals Loser West Finals Loser
0 2003 San Antonio Spurs New Jersey Nets 2016-04-02 Tim Duncan Gregg Popovich Detroit Pistons Dallas Mavericks
1 2002 Los Angeles Lakers New Jersey Nets 2000-04-01 Shaquille O'Neal Phil Jackson Boston Celtics Sacramento Kings
2 1998 Chicago Bulls Utah Jazz 2016-04-02 Michael Jordan Phil Jackson Indiana Pacers Los Angeles Lakers
3 1997 Chicago Bulls Utah Jazz 2016-04-02 Michael Jordan Phil Jackson Miami Heat Houston Rockets
4 1996 Chicago Bulls Seattle SuperSonics 2016-04-02 Michael Jordan Phil Jackson Orlando Magic Utah Jazz
5 1993 Chicago Bulls Phoenix Suns 2016-04-02 Michael Jordan Phil Jackson New York Knicks Seattle Supersonics
6 1992 Chicago Bulls Portland Trail Blazers 2016-04-02 Michael Jordan Phil Jackson Cleveland Cavaliers Utah Jazz
7 1991 Chicago Bulls Los Angeles Lakers 2016-04-01 Michael Jordan Phil Jackson Detroit Pistons Portland Trail Blazers
8 1990 Detroit Pistons Portland Trail Blazers 2016-04-01 Isiah Thomas Chuck Daly Chicago Bulls Phoenix Suns
9 1989 Detroit Pistons Los Angeles Lakers 2000-04-01 Joe Dumars Chuck Daly Chicago Bulls Phoenix Suns
10 1988 Los Angeles Lakers Detroit Pistons 2016-04-03 James Worthy Pat Riley Boston Celtics Dallas Mavericks
11 1987 Los Angeles Lakers Boston Celtics 2016-04-02 Magic Johnson Pat Riley Detroit Pistons Seattle Supersonics
12 1985 Los Angeles Lakers Boston Celtics 2016-04-02 Kareem Abdul-Jabbar Pat Riley Philadelphia 76ers Denver Nuggets

In [20]:
dict_Jordan = {}

for i in range(13): 
    if df_NBA_Champ_Jordan['Champion'][i] in dict_Jordan.keys(): #check and see if in dictionary -- if not, add one to value
        dict_Jordan[df_NBA_Champ_Jordan['Champion'][i]] = 1 + dict_Jordan.get(df_NBA_Champ_Jordan['Champion'][i])
    else: # add to dictionary if not in it already
        dict_Jordan[df_NBA_Champ_Jordan['Champion'][i]] = 1 

total_Jordan = 0 #calculating HHI
for i in dict_Jordan.values():
    total_Jordan = total_Jordan + i*i
    
HHI_Jordan = total_Jordan / 13
print("The HHI during the years Jordan played is: ", round(HHI_Jordan, 2))

HHIs = pd.DataFrame({'Name':['Lebron James Era', 'Michael Jordan Era'], 'HHI':[HHI_Lebron, HHI_Jordan]})
HHIs = HHIs.set_index(['Name'])

fig, ax = plt.subplots()
plt.style.use('bmh')
HHIs.plot(ax=ax, legend=False, kind = 'bar',color = ['blue','purple'], alpha = 0.65,rot = 0)
ax.set_xlabel("Players", fontsize = 14)
ax.set_ylabel('HHI',fontsize = 14)
ax.set_title('HHI Across Eras', fontsize = 14)


The HHI during the years Jordan played is:  4.38
Out[20]:
<matplotlib.text.Text at 0x11c1f53c8>

The HHI during Jordan's years was much higher than that during Lebron's years which suggests that talent was concentrated in a few select teams during Jordan's time. This would allow him to have better statistics during his era as the other teams he played in the league were not nearly up to par. James, on the other hand, faces a much more even playing field and thus it is harder for him, compared to Jordan, to accumulate the same statistics. This leads us to believe that perhaps Lebon's statistics and the narrative that is painted by the above analysis may be somewhat understating Lebron's abilities.


In [ ]: