Skip to content

Instantly share code, notes, and snippets.

@EvanZ
Last active December 22, 2019 17:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EvanZ/48bf713ce9eb14f28d58 to your computer and use it in GitHub Desktop.
Save EvanZ/48bf713ce9eb14f28d58 to your computer and use it in GitHub Desktop.
RAPM tutorial 2015 data
{
"metadata": {
"name": "",
"signature": "sha256:92ccaf2e31ad75afe47fb6a382eb103dcec24aac1e52eedb12c28b43112443dc"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Regularized +/- (RAPM) in Python using scikit-learn"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First thing we do is import matchup data. My matchup data (obtained by scraping play-by-play from a couple different websites) is stored in a MongoDB collection which has a \"document\" (i.e. JSON object) for each \"stint\" in a game. A stint is defined as a series of possessions in between player substitutions. Every time a player (or more than one) is subbed into the game, a new stint is created. For this tutorial I'll be working with data from the current season (2014-15)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import json # a built-in Python module for dealing with JSON data\n",
"data = [] # create an empty array to hold all the stints\n",
"# open the file and read the data!\n",
"with open('/Users/evanzamir/PycharmProjects/sklearn_tutorial/matchups.json') as units_file:\n",
" for j in units_file:\n",
" data.append(json.loads(j)) "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 381
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# \"pretty\" print the first stint, which in this case describes a matchup in a CHA-MIA game last season.\n",
"\n",
"from pprint import pprint\n",
"pprint(data[0]) "
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"{u'Bulls': {u'entered': [],\n",
" u'exited': [],\n",
" u'on': [u'Aaron Brooks',\n",
" u'Derrick Rose',\n",
" u'Nikola Mirotic',\n",
" u'Taj Gibson',\n",
" u'Joakim Noah'],\n",
" u'stats': {u'dreb': 0,\n",
" u'drebx': 1,\n",
" u'fg2m': 0,\n",
" u'fg3m': 0,\n",
" u'fgm': 0,\n",
" u'fgx': 2,\n",
" u'foul': 1,\n",
" u'fta': 0,\n",
" u'ftm': 0,\n",
" u'non_steal_tov': 0,\n",
" u'oreb': 0,\n",
" u'orebx': 2,\n",
" u'poss': 3,\n",
" u'pts': 0,\n",
" u'team_tov': 0,\n",
" u'time': 0,\n",
" u'tov': 1}},\n",
" u'Cavaliers': {u'entered': [],\n",
" u'exited': [],\n",
" u'on': [u'Kyrie Irving',\n",
" u'Iman Shumpert',\n",
" u'J.R. Smith',\n",
" u'James Jones',\n",
" u'Timofey Mozgov'],\n",
" u'stats': {u'dreb': 2,\n",
" u'drebx': 0,\n",
" u'fg2m': 1,\n",
" u'fg3m': 0,\n",
" u'fgm': 1,\n",
" u'fgx': 1,\n",
" u'foul': 2,\n",
" u'fta': 0,\n",
" u'ftm': 0,\n",
" u'non_steal_tov': 1,\n",
" u'oreb': 1,\n",
" u'orebx': 0,\n",
" u'poss': 3,\n",
" u'pts': 2,\n",
" u'team_tov': 0,\n",
" u'time': 0,\n",
" u'tov': 2}},\n",
" u'_id': {u'$oid': u'54e597185bca6dc9e8006033'},\n",
" u'as': 79,\n",
" u'away': u'Cavaliers',\n",
" u'date': u'2015-02-12',\n",
" u'end': u'10:25',\n",
" u'espn_id': u'400579092',\n",
" u'home': u'Bulls',\n",
" u'hs': 87,\n",
" u'mid': 0,\n",
" u'plays': [{u'id': {u'$oid': u'54e58da65bca6dc72005919f'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a0'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a1'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a2'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a3'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a4'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a5'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a6'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a7'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a8'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591a9'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591aa'}},\n",
" {u'id': {u'$oid': u'54e58da65bca6dc7200591ab'}}],\n",
" u'q': 4,\n",
" u'season': u'2015',\n",
" u'start': u'12:00',\n",
" u'time': 95,\n",
" u'url': u'http://scores.nbcsports.msnbc.com/nba/pbp.asp?gamecode=2015021204'}\n"
]
}
],
"prompt_number": 382
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can see there's a ton of data even for one stint. The main things we care about are the players in the 'on' and 'off' arrays under each team, the possessions (.stats.poss) and the points scored during the stint ('.stats.pts')."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To compute RAPM we'll be using a very popular machine learning toolkit in Python called scikit-learn (abbreviated sklearn). Within sklearn there are many different ML algorithms. RAPM uses a technique called Ridge Regression. But before we get to that, we will want to look at some \"helper\" functions that will be useful in transforming our stint data to a form that sklearn requires."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we will import a class called DictVectorizer which transforms a list of arrays into a list of Python dictionaries (\"dicts\" in Python or \"hashes\" or \"maps\" in other languages). In our stint objects there is an array containing the 5 players on the court for each team. When we do the regression, we will actually want to create a much larger array containing as many columns as there are players in the league (around 480 or so). *DictVectorizer* will help us do that quite easily as shown below."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# To demonstrate how DictVectorizer works...\n",
"# Create a small list of lists with \"fake\" units\n",
"\n",
"units = [['Stephen Curry','Klay Thompson','Harrison Barnes','Draymond Green','Andrew Bogut'],\n",
" ['Stephen Curry','Klay Thompson','Harrison Barnes','Draymond Green','Andrew Bogut'],\n",
" ['Shaun Livingston','Klay Thompson','Harrison Barnes','Draymond Green','Andrew Bogut'],\n",
" ['Shaun Livingston','Klay Thompson','Andre Iguodala','Draymond Green','Andrew Bogut'],\n",
" ['Leandro Barbosa','Shaun Livingston','Andre Iguodala','Harrison Barnes','Draymond Green']]\n",
"\n",
"from sklearn.feature_extraction import DictVectorizer\n",
"v = DictVectorizer(sparse=False)\n",
"list_dicts = []\n",
"\n",
"# For each unit we want to create a dict containing the players' names as keys and the value 1 as the value.\n",
"# Later the value will be +1 if the player is playing at home and -1 if he is away.\n",
"\n",
"for unit in units:\n",
" list_dicts.append({name: 1 for name in unit})\n",
"print(list_dicts)\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[{'Andrew Bogut': 1, 'Klay Thompson': 1, 'Draymond Green': 1, 'Harrison Barnes': 1, 'Stephen Curry': 1}, {'Andrew Bogut': 1, 'Klay Thompson': 1, 'Draymond Green': 1, 'Harrison Barnes': 1, 'Stephen Curry': 1}, {'Klay Thompson': 1, 'Andrew Bogut': 1, 'Shaun Livingston': 1, 'Draymond Green': 1, 'Harrison Barnes': 1}, {'Klay Thompson': 1, 'Andrew Bogut': 1, 'Shaun Livingston': 1, 'Draymond Green': 1, 'Andre Iguodala': 1}, {'Shaun Livingston': 1, 'Leandro Barbosa': 1, 'Harrison Barnes': 1, 'Andre Iguodala': 1, 'Draymond Green': 1}]\n"
]
}
],
"prompt_number": 383
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# This is where magic happens.\n",
"# The function fit_transform has turned our list of dicts into a list of arrays containing enough columns\n",
"# for all the players in this fake data set.\n",
"# The variable v, an instance of DictVectorizer, is able to keep track of all this bookkeeping for us.\n",
"# Basically, it's a really useful thing to have for what we're about to do and eliminates\n",
"# writing a metric ton of our own code.\n",
"\n",
"X = v.fit_transform(list_dicts)\n",
"print(X)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[[ 0. 1. 1. 1. 1. 0. 0. 1.]\n",
" [ 0. 1. 1. 1. 1. 0. 0. 1.]\n",
" [ 0. 1. 1. 1. 1. 0. 1. 0.]\n",
" [ 1. 1. 1. 0. 1. 0. 1. 0.]\n",
" [ 1. 0. 1. 1. 0. 1. 1. 0.]]\n"
]
}
],
"prompt_number": 384
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# We can even take the inverse transform and get back the list of dicts!\n",
"\n",
"x = v.inverse_transform(X)\n",
"print(x)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[{'Klay Thompson': 1.0, 'Andrew Bogut': 1.0, 'Draymond Green': 1.0, 'Harrison Barnes': 1.0, 'Stephen Curry': 1.0}, {'Klay Thompson': 1.0, 'Andrew Bogut': 1.0, 'Draymond Green': 1.0, 'Harrison Barnes': 1.0, 'Stephen Curry': 1.0}, {'Klay Thompson': 1.0, 'Shaun Livingston': 1.0, 'Andrew Bogut': 1.0, 'Draymond Green': 1.0, 'Harrison Barnes': 1.0}, {'Klay Thompson': 1.0, 'Shaun Livingston': 1.0, 'Andrew Bogut': 1.0, 'Draymond Green': 1.0, 'Andre Iguodala': 1.0}, {'Shaun Livingston': 1.0, 'Harrison Barnes': 1.0, 'Leandro Barbosa': 1.0, 'Draymond Green': 1.0, 'Andre Iguodala': 1.0}]\n"
]
}
],
"prompt_number": 371
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# And we can easily get the names of all the players in the data set!\n",
"# W00t\n",
"\n",
"print(v.get_feature_names())"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"['Andre Iguodala', 'Andrew Bogut', 'Draymond Green', 'Harrison Barnes', 'Klay Thompson', 'Leandro Barbosa', 'Shaun Livingston', 'Stephen Curry']\n"
]
}
],
"prompt_number": 372
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we're going to iterate through our matchup **data** and create three variables: 1) **units** is a list of dicts of the home and away players for each stint with a +1/-1 indicating which side they are on; 2) **points** is a list containing the point differential (normalized to 100 possessions) for each stint; 3) **weights** is simply the number of possessions for each stint."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"units = []\n",
"points = []\n",
"weights = []\n",
"\n",
"for d in data:\n",
" home = d['home']\n",
" away = d['away']\n",
" home_poss = d[home]['stats']['poss']\n",
" away_poss = d[away]['stats']['poss']\n",
" point_diff = 100*(d[home]['stats']['pts']-d[away]['stats']['pts'])/((home_poss+away_poss+0.01)/2.)\n",
" home_unit = {name:1 for name in d[home]['on']}\n",
" away_unit = {name:-1 for name in d[away]['on']}\n",
" stint = home_unit.copy()\n",
" stint.update(away_unit)\n",
" if (home_poss+away_poss) >= 2: # to avoid some ill-conditioning we only use stints that have possessions >= 1\n",
" units.append(stint)\n",
" points.append(point_diff)\n",
" weights.append((home_poss+away_poss)/2.)\n",
"print(len(units),len(points),len(weights))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(20613, 20613, 20613)\n"
]
}
],
"prompt_number": 385
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Now we employ DictVectorizer to do its magic\n",
"\n",
"u = DictVectorizer(sparse=False)\n",
"u_mat = u.fit_transform(units)\n",
"print(u_mat) # a giant list of lists where each array contains five +1's, five -1's, and a whole mess of 0's\n",
"print(points[:25]) # just showing the first 25 stints\n",
"print(weights[:100]) # just showing the first 100 stints"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[[ 0. 1. 0. ..., 0. 0. 0.]\n",
" [ 0. 0. 0. ..., 0. 0. 0.]\n",
" [ 0. 0. 0. ..., 0. 0. 0.]\n",
" ..., \n",
" [ 0. 0. 0. ..., 0. 0. 0.]\n",
" [ 0. 0. 0. ..., 0. 0. 0.]\n",
" [ 0. 0. 0. ..., 0. 0. 0.]]\n",
"[-66.55574043261231, 39.960039960039964, 132.89036544850498, -79.84031936127745, -114.12268188302426, 199.6007984031936, 99.50248756218906, -132.89036544850498, -199.50124688279303, 132.89036544850498, -119.76047904191617, 0.0, 44.39511653718091, 0.0, -114.12268188302426, 0.0, 39.920159680638726, -99.50248756218906, -66.59267480577137, -39.920159680638726, -39.920159680638726, -33.277870216306155, 0.0, 39.920159680638726, 66.55574043261231]\n",
"[3.0, 5.0, 1.5, 2.5, 3.5, 2.5, 1.0, 1.5, 2.0, 1.5, 2.5, 2.0, 4.5, 3.5, 3.5, 4.0, 2.5, 1.0, 4.5, 2.5, 2.5, 3.0, 1.0, 2.5, 3.0, 1.0, 1.0, 3.5, 5.0, 3.0, 2.0, 1.5, 1.5, 3.5, 2.5, 3.0, 1.0, 1.5, 2.0, 2.5, 2.5, 3.0, 1.5, 5.0, 2.5, 5.0, 5.0, 1.0, 1.0, 1.5, 6.0, 1.0, 1.5, 4.5, 3.5, 1.0, 1.5, 3.5, 2.0, 1.0, 3.0, 1.5, 2.5, 4.0, 5.5, 2.5, 2.5, 1.0, 1.5, 2.0, 2.0, 2.0, 3.0, 1.0, 4.0, 3.0, 4.0, 4.5, 3.0, 1.0, 2.5, 7.0, 2.0, 2.0, 1.0, 7.0, 3.5, 1.0, 2.0, 3.0, 3.5, 2.5, 1.0, 2.0, 1.0, 1.0, 4.5, 2.5, 3.0, 2.5]\n"
]
}
],
"prompt_number": 386
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# The first 25 players alphabetically in the data set\n",
"\n",
"players = u.get_feature_names()\n",
"pprint(u.get_feature_names()[:25])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[u'A.J. Price',\n",
" u'Aaron Brooks',\n",
" u'Aaron Gordon',\n",
" u'Adreian Payne',\n",
" u'Al Horford',\n",
" u'Al Jefferson',\n",
" u'Al-Farouq Aminu',\n",
" u'Alan Anderson',\n",
" u'Alec Burks',\n",
" u'Alex Kirk',\n",
" u'Alex Len',\n",
" u'Alexey Shved',\n",
" u'Alexis Ajinca',\n",
" u'Allen Crabbe',\n",
" u'Alonzo Gee',\n",
" u\"Amar'e Stoudemire\",\n",
" u'Amir Johnson',\n",
" u'Anderson Varejao',\n",
" u'Andre Dawkins',\n",
" u'Andre Drummond',\n",
" u'Andre Iguodala',\n",
" u'Andre Miller',\n",
" u'Andre Roberson',\n",
" u'Andrea Bargnani',\n",
" u'Andrei Kirilenko']\n"
]
}
],
"prompt_number": 394
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# perform the inverse transform on one stint just to double check it makes sense\n",
"\n",
"pprint(u.inverse_transform(u_mat)[:1])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[{u'Aaron Brooks': 1.0,\n",
" u'Derrick Rose': 1.0,\n",
" u'Iman Shumpert': -1.0,\n",
" u'J.R. Smith': -1.0,\n",
" u'James Jones': -1.0,\n",
" u'Joakim Noah': 1.0,\n",
" u'Kyrie Irving': -1.0,\n",
" u'Nikola Mirotic': 1.0,\n",
" u'Taj Gibson': 1.0,\n",
" u'Timofey Mozgov': -1.0}]\n"
]
}
],
"prompt_number": 388
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now the fun stuff begins! We import the **linear_model** class and use the function **RidgeCV** to perform ridge regression on our data set using five-fold cross validation. Briefly, the idea here is to pick the optimal value of *alpha* for regularizing the data (i.e. so it fits the data best)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from sklearn import linear_model\n",
"clf = linear_model.RidgeCV(alphas=(numpy.array([0.01,0.1,1.0,10,100,500,1000,2000,5000])),cv=5)\n",
"clf.fit(u_mat,points,sample_weight=weights)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 389,
"text": [
"RidgeCV(alphas=array([ 1.00000e-02, 1.00000e-01, 1.00000e+00, 1.00000e+01,\n",
" 1.00000e+02, 5.00000e+02, 1.00000e+03, 2.00000e+03,\n",
" 5.00000e+03]),\n",
" cv=5, fit_intercept=True, gcv_mode=None, loss_func=None,\n",
" normalize=False, score_func=None, scoring=None, store_cv_values=False)"
]
}
],
"prompt_number": 389
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Here is the value of alpha that RidgeCV selected. We could probably add a few more values to test above too...\n",
"# but this is just a tutorial :)\n",
"\n",
"print(clf.alpha_)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"500.0\n"
]
}
],
"prompt_number": 390
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we want to get the coefficients that RidgeCV found for our \"optimal\" solution. The coefficients for each player are contained in an attribute of the class called **coef_**. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ratings = []\n",
"for player in players:\n",
" ratings.append((player,clf.coef_[players.index(player)]))\n",
"ratings.sort(key=lambda tup: tup[1],reverse=True) # sort by rating in descending order"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 395
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And here are the ratings! Now, remember this is for one season of data. The ratings are obviously quite noisy. And that's why it is often not very useful to look at just one season of data. But this is enough to give you the basic idea of how it's done."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for idx, rating in enumerate(ratings):\n",
" print(idx+1, \"{}\".format(rating[0]), \"{0:.2f}\".format(rating[1]))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(1, 'James Harden', '8.99')\n",
"(2, 'Manu Ginobili', '8.40')\n",
"(3, 'Kyle Korver', '6.78')\n",
"(4, 'Draymond Green', '6.67')\n",
"(5, 'Markieff Morris', '6.50')\n",
"(6, 'Stephen Curry', '6.45')\n",
"(7, 'Damian Lillard', '6.32')\n",
"(8, 'Cody Zeller', '6.04')\n",
"(9, 'Anthony Davis', '5.85')\n",
"(10, 'Zach Randolph', '5.74')\n",
"(11, 'Kyle Lowry', '5.73')\n",
"(12, 'Kawhi Leonard', '5.71')\n",
"(13, 'LeBron James', '5.67')\n",
"(14, 'Khris Middleton', '5.63')\n",
"(15, 'Michael Kidd-Gilchrist', '5.54')\n",
"(16, 'Carmelo Anthony', '5.48')\n",
"(17, 'Jeff Teague', '5.27')\n",
"(18, 'Luol Deng', '5.25')\n",
"(19, 'C.J. Miles', '5.11')\n",
"(20, 'Tony Allen', '4.91')\n",
"(21, 'Jared Dudley', '4.88')\n",
"(22, 'James Johnson', '4.88')\n",
"(23, 'DeMarcus Cousins', '4.81')\n",
"(24, 'Patrick Patterson', '4.52')\n",
"(25, 'Gordon Hayward', '4.47')\n",
"(26, 'Chris Paul', '4.45')\n",
"(27, 'Ty Lawson', '4.43')\n",
"(28, 'Kyrie Irving', '4.37')\n",
"(29, 'Anthony Morrow', '4.32')\n",
"(30, 'Nene', '4.25')\n",
"(31, 'Lou Williams', '4.22')\n",
"(32, 'Jusuf Nurkic', '4.19')\n",
"(33, 'Chandler Parsons', '4.17')\n",
"(34, 'Klay Thompson', '4.14')\n",
"(35, 'Thabo Sefolosha', '4.14')\n",
"(36, 'Tyson Chandler', '4.10')\n",
"(37, 'Ben McLemore', '4.06')\n",
"(38, 'LaMarcus Aldridge', '4.06')\n",
"(39, 'Tyreke Evans', '3.96')\n",
"(40, 'Andre Iguodala', '3.96')\n",
"(41, 'Al-Farouq Aminu', '3.91')\n",
"(42, 'Darren Collison', '3.86')\n",
"(43, 'Tyler Hansbrough', '3.85')\n",
"(44, 'Josh McRoberts', '3.83')\n",
"(45, 'Marcin Gortat', '3.74')\n",
"(46, 'Kevin Durant', '3.73')\n",
"(47, 'Cory Jefferson', '3.71')\n",
"(48, 'George Hill', '3.56')\n",
"(49, 'Patrick Mills', '3.44')\n",
"(50, 'Lavoy Allen', '3.40')\n",
"(51, 'Paul Millsap', '3.31')\n",
"(52, 'Kendall Marshall', '3.24')\n",
"(53, 'Dwight Howard', '3.16')\n",
"(54, 'Jrue Holiday', '3.13')\n",
"(55, 'Dirk Nowitzki', '3.11')\n",
"(56, 'Marc Gasol', '3.10')\n",
"(57, 'Blake Griffin', '3.05')\n",
"(58, 'Serge Ibaka', '2.93')\n",
"(59, 'DeMar DeRozan', '2.89')\n",
"(60, 'Matt Barnes', '2.84')\n",
"(61, 'Deron Williams', '2.82')\n",
"(62, 'J.J. Redick', '2.74')\n",
"(63, 'Aron Baynes', '2.72')\n",
"(64, 'Aaron Brooks', '2.72')\n",
"(65, 'Rudy Gay', '2.61')\n",
"(66, 'Robert Sacre', '2.57')\n",
"(67, \"Amar'e Stoudemire\", '2.55')\n",
"(68, 'Dwyane Wade', '2.52')\n",
"(69, 'Andre Drummond', '2.51')\n",
"(70, 'Derrick Rose', '2.46')\n",
"(71, 'Shawn Marion', '2.45')\n",
"(72, 'Kemba Walker', '2.45')\n",
"(73, 'Jimmy Butler', '2.43')\n",
"(74, 'Monta Ellis', '2.40')\n",
"(75, 'Andrew Bogut', '2.38')\n",
"(76, 'Jonas Jerebko', '2.37')\n",
"(77, 'Terrence Jones', '2.37')\n",
"(78, 'Wesley Matthews', '2.34')\n",
"(79, 'John Wall', '2.34')\n",
"(80, 'Quincy Acy', '2.31')\n",
"(81, 'Gerald Wallace', '2.30')\n",
"(82, 'Kendrick Perkins', '2.28')\n",
"(83, 'Tristan Thompson', '2.25')\n",
"(84, 'Hassan Whiteside', '2.24')\n",
"(85, 'David West', '2.24')\n",
"(86, 'Giannis Antetokounmpo', '2.23')\n",
"(87, 'Zaza Pachulia', '2.23')\n",
"(88, 'Tim Duncan', '2.21')\n",
"(89, 'Mirza Teletovic', '2.20')\n",
"(90, 'Alan Anderson', '2.18')\n",
"(91, 'Matt Bonner', '2.17')\n",
"(92, 'Jeff Adrien', '2.16')\n",
"(93, 'Jason Terry', '2.16')\n",
"(94, 'Eric Bledsoe', '2.14')\n",
"(95, 'Timofey Mozgov', '2.10')\n",
"(96, 'Luis Scola', '2.09')\n",
"(97, 'Kenneth Faried', '2.07')\n",
"(98, 'Wayne Ellington', '2.06')\n",
"(99, 'Boris Diaw', '2.00')\n",
"(100, 'Jerryd Bayless', '1.99')\n",
"(101, 'Ricky Rubio', '1.98')\n",
"(102, 'Harrison Barnes', '1.97')\n",
"(103, 'Robert Covington', '1.95')\n",
"(104, 'Marreese Speights', '1.95')\n",
"(105, 'Dante Exum', '1.94')\n",
"(106, 'Brandon Jennings', '1.94')\n",
"(107, 'Thomas Robinson', '1.93')\n",
"(108, 'Langston Galloway', '1.92')\n",
"(109, 'Dorell Wright', '1.92')\n",
"(110, 'J.J. Barea', '1.88')\n",
"(111, 'Wesley Johnson', '1.87')\n",
"(112, 'C.J. Watson', '1.86')\n",
"(113, 'Nene Hilario', '1.84')\n",
"(114, 'Mo Williams', '1.80')\n",
"(115, 'Kosta Koufos', '1.78')\n",
"(116, 'Tony Snell', '1.77')\n",
"(117, 'Chris Johnson', '1.75')\n",
"(118, 'Kentavious Caldwell-Pope', '1.73')\n",
"(119, 'Mike Dunleavy', '1.73')\n",
"(120, 'Marcus Smart', '1.72')\n",
"(121, 'Pero Antic', '1.68')\n",
"(122, 'Glenn Robinson III', '1.67')\n",
"(123, 'Kevin Love', '1.66')\n",
"(124, 'Cory Joseph', '1.65')\n",
"(125, 'Tobias Harris', '1.59')\n",
"(126, 'Joel Freeland', '1.57')\n",
"(127, 'Tayshaun Prince', '1.56')\n",
"(128, 'Bradley Beal', '1.52')\n",
"(129, 'Kirk Hinrich', '1.52')\n",
"(130, 'Paul Pierce', '1.51')\n",
"(131, 'Justin Holiday', '1.48')\n",
"(132, 'Chuck Hayes', '1.44')\n",
"(133, 'Caron Butler', '1.44')\n",
"(134, 'Enes Kanter', '1.44')\n",
"(135, 'Thaddeus Young', '1.42')\n",
"(136, 'Pau Gasol', '1.40')\n",
"(137, 'Robbie Hummel', '1.40')\n",
"(138, 'Trevor Ariza', '1.40')\n",
"(139, 'Beno Udrih', '1.39')\n",
"(140, 'Quincy Miller', '1.36')\n",
"(141, 'Courtney Lee', '1.36')\n",
"(142, 'Pablo Prigioni', '1.34')\n",
"(143, 'Elliot Williams', '1.33')\n",
"(144, 'Rudy Gobert', '1.32')\n",
"(145, 'Nick Young', '1.28')\n",
"(146, 'Mike Scott', '1.27')\n",
"(147, 'Andre Roberson', '1.20')\n",
"(148, 'Kenyon Martin', '1.18')\n",
"(149, 'P.J. Tucker', '1.18')\n",
"(150, 'Shayne Whittington', '1.17')\n",
"(151, 'Russell Westbrook', '1.16')\n",
"(152, 'Rajon Rondo', '1.16')\n",
"(153, 'Nick Calathes', '1.14')\n",
"(154, 'Tiago Splitter', '1.08')\n",
"(155, 'Garrett Temple', '1.03')\n",
"(156, 'K.J. McDaniels', '1.02')\n",
"(157, 'Greg Monroe', '1.01')\n",
"(158, 'Marcus Thornton', '0.99')\n",
"(159, 'Tim Frazier', '0.97')\n",
"(160, 'Ryan Kelly', '0.96')\n",
"(161, 'Jared Sullinger', '0.94')\n",
"(162, 'Chris Copeland', '0.93')\n",
"(163, 'Gerald Green', '0.92')\n",
"(164, 'Jerami Grant', '0.91')\n",
"(165, 'Arron Afflalo', '0.91')\n",
"(166, 'Cameron Bairstow', '0.86')\n",
"(167, 'Devyn Marble', '0.81')\n",
"(168, 'Gerald Henderson', '0.79')\n",
"(169, 'Donatas Motiejunas', '0.78')\n",
"(170, 'Steven Adams', '0.74')\n",
"(171, 'Kyle Singler', '0.73')\n",
"(172, 'Isaiah Thomas', '0.68')\n",
"(173, 'Ronnie Price', '0.68')\n",
"(174, 'Nazr Mohammed', '0.67')\n",
"(175, 'Evan Fournier', '0.67')\n",
"(176, 'Miroslav Raduljica', '0.66')\n",
"(177, 'Victor Claver', '0.66')\n",
"(178, 'Marvin Williams', '0.65')\n",
"(179, 'Carlos Boozer', '0.63')\n",
"(180, 'Miles Plumlee', '0.61')\n",
"(181, 'Danny Green', '0.59')\n",
"(182, 'Bismack Biyombo', '0.59')\n",
"(183, 'James Michael McAdoo', '0.56')\n",
"(184, 'Henry Sims', '0.55')\n",
"(185, 'Shelvin Mack', '0.54')\n",
"(186, 'Dante Cunningham', '0.53')\n",
"(187, 'Andrew Wiggins', '0.53')\n",
"(188, 'Xavier Henry', '0.52')\n",
"(189, 'Nikola Pekovic', '0.50')\n",
"(190, 'Elfrid Payton', '0.49')\n",
"(191, 'Reggie Bullock', '0.48')\n",
"(192, 'Jimmer Fredette', '0.47')\n",
"(193, 'Kevin Martin', '0.45')\n",
"(194, 'Travis Wear', '0.41')\n",
"(195, 'DeAndre Jordan', '0.41')\n",
"(196, 'Phil Pressey', '0.40')\n",
"(197, 'Trevor Booker', '0.39')\n",
"(198, 'Rasual Butler', '0.34')\n",
"(199, 'Mike Conley', '0.33')\n",
"(200, 'Jamal Crawford', '0.31')\n",
"(201, 'Luigi Datome', '0.30')\n",
"(202, 'Donald Sloan', '0.30')\n",
"(203, 'Chris Bosh', '0.29')\n",
"(204, 'Willie Green', '0.29')\n",
"(205, 'JaMychal Green', '0.29')\n",
"(206, 'Ekpe Udoh', '0.26')\n",
"(207, 'Nate Wolters', '0.24')\n",
"(208, 'Noah Vonleh', '0.24')\n",
"(209, 'David Lee', '0.22')\n",
"(210, 'Meyers Leonard', '0.22')\n",
"(211, 'Greg Stiemsma', '0.22')\n",
"(212, 'Eric Moreland', '0.22')\n",
"(213, 'Darius Miller', '0.18')\n",
"(214, 'James Young', '0.18')\n",
"(215, 'Robin Lopez', '0.17')\n",
"(216, 'Mason Plumlee', '0.16')\n",
"(217, 'Tyler Ennis', '0.16')\n",
"(218, 'Jannero Pargo', '0.15')\n",
"(219, 'Malcolm Lee', '0.15')\n",
"(220, 'Steve Blake', '0.15')\n",
"(221, 'Hedo Turkoglu', '0.13')\n",
"(222, 'Tyrus Thomas', '0.10')\n",
"(223, 'Kelly Olynyk', '0.10')\n",
"(224, 'Devin Harris', '0.08')\n",
"(225, 'Mitch McGary', '0.07')\n",
"(226, 'Maurice Harkless', '0.07')\n",
"(227, 'Tyler Johnson', '0.02')\n",
"(228, 'Russ Smith', '0.02')\n",
"(229, 'Ricky Ledo', '-0.02')\n",
"(230, 'Amir Johnson', '-0.03')\n",
"(231, 'T.J. Warren', '-0.03')\n",
"(232, 'Reggie Evans', '-0.06')\n",
"(233, 'C.J. McCollum', '-0.12')\n",
"(234, 'Anthony Tolliver', '-0.13')\n",
"(235, 'Kalin Lucas', '-0.13')\n",
"(236, 'Chris Andersen', '-0.13')\n",
"(237, 'Jason Maxiell', '-0.14')\n",
"(238, 'Bojan Bogdanovic', '-0.14')\n",
"(239, 'Joel Anthony', '-0.15')\n",
"(240, 'Jae Crowder', '-0.18')\n",
"(241, \"Toure' Murry\", '-0.19')\n",
"(242, 'Jared Cunningham', '-0.19')\n",
"(243, 'C.J. Wilcox', '-0.20')\n",
"(244, 'Gal Mekel', '-0.22')\n",
"(245, 'Glen Rice Jr.', '-0.23')\n",
"(246, 'Dwight Powell', '-0.29')\n",
"(247, 'Ryan Anderson', '-0.32')\n",
"(248, 'Corey Brewer', '-0.32')\n",
"(249, 'Avery Bradley', '-0.34')\n",
"(250, 'Randy Foye', '-0.34')\n",
"(251, 'Ed Davis', '-0.37')\n",
"(252, 'John Lucas III', '-0.40')\n",
"(253, 'Joey Dorsey', '-0.40')\n",
"(254, 'DeJuan Blair', '-0.41')\n",
"(255, 'Bernard James', '-0.42')\n",
"(256, 'Shannon Brown', '-0.43')\n",
"(257, 'Marcus Morris', '-0.43')\n",
"(258, 'Iman Shumpert', '-0.44')\n",
"(259, 'DeMarre Carroll', '-0.44')\n",
"(260, 'Mike Muscala', '-0.44')\n",
"(261, 'Michael Carter-Williams', '-0.46')\n",
"(262, 'Andre Dawkins', '-0.47')\n",
"(263, 'Kostas Papanikolaou', '-0.47')\n",
"(264, 'Jordan Adams', '-0.48')\n",
"(265, 'Bruno Caboclo', '-0.50')\n",
"(266, 'Lucas Nogueira', '-0.51')\n",
"(267, 'Eric Gordon', '-0.53')\n",
"(268, 'Zoran Dragic', '-0.56')\n",
"(269, 'Al Horford', '-0.57')\n",
"(270, 'Lorenzo Brown', '-0.60')\n",
"(271, 'P.J. Hairston', '-0.62')\n",
"(272, 'Danilo Gallinari', '-0.62')\n",
"(273, 'Brian Roberts', '-0.62')\n",
"(274, 'Richard Jefferson', '-0.63')\n",
"(275, 'Shabazz Muhammad', '-0.65')\n",
"(276, 'Mike Malone', '-0.68')\n",
"(277, 'Glen Davis', '-0.68')\n",
"(278, 'Otto Porter', '-0.70')\n",
"(279, 'Alexis Ajinca', '-0.71')\n",
"(280, 'Roy Hibbert', '-0.72')\n",
"(281, 'Alex Len', '-0.73')\n",
"(282, 'Alex Kirk', '-0.74')\n",
"(283, 'Goran Dragic', '-0.74')\n",
"(284, 'Joe Johnson', '-0.76')\n",
"(285, 'Joakim Noah', '-0.79')\n",
"(286, 'Allen Crabbe', '-0.80')\n",
"(287, 'Omer Asik', '-0.81')\n",
"(288, 'Francisco Garcia', '-0.82')\n",
"(289, 'Jarnell Stokes', '-0.83')\n",
"(290, 'Rodney Hood', '-0.83')\n",
"(291, 'Mike Miller', '-0.85')\n",
"(292, 'Ognjen Kuzmic', '-0.85')\n",
"(293, 'Nikola Mirotic', '-0.85')\n",
"(294, 'Charlie Villanueva', '-0.89')\n",
"(295, 'J.R. Smith', '-0.90')\n",
"(296, 'Taj Gibson', '-0.91')\n",
"(297, 'Toney Douglas', '-0.92')\n",
"(298, 'Ronny Turiaf', '-0.93')\n",
"(299, 'Kevin Garnett', '-0.96')\n",
"(300, 'Jeff Ayres', '-0.97')\n",
"(301, 'Shavlik Randolph', '-0.97')\n",
"(302, 'Julius Randle', '-0.98')\n",
"(303, 'Reggie Williams', '-0.99')\n",
"(304, 'Trey Burke', '-1.01')\n",
"(305, 'Louis Amundson', '-1.05')\n",
"(306, 'Drew Gordon', '-1.06')\n",
"(307, 'O.J. Mayo', '-1.06')\n",
"(308, 'Dewayne Dedmon', '-1.09')\n",
"(309, 'Chris Douglas-Roberts', '-1.13')\n",
"(310, 'Larry Sanders', '-1.15')\n",
"(311, 'Nikola Vucevic', '-1.15')\n",
"(312, 'Drew Gooden', '-1.16')\n",
"(313, 'Mario Chalmers', '-1.17')\n",
"(314, 'Reggie Jackson', '-1.18')\n",
"(315, \"E'Twaun Moore\", '-1.20')\n",
"(316, 'Jeremy Lin', '-1.20')\n",
"(317, 'Clint Capela', '-1.20')\n",
"(318, 'Gary Harris', '-1.21')\n",
"(319, 'Nick Johnson', '-1.22')\n",
"(320, 'Jeremy Evans', '-1.23')\n",
"(321, 'Will Barton', '-1.24')\n",
"(322, 'Jeff Withey', '-1.24')\n",
"(323, 'Luc Richard Mbah a Moute', '-1.24')\n",
"(324, 'James Ennis', '-1.29')\n",
"(325, 'Tyler Zeller', '-1.29')\n",
"(326, 'John Henson', '-1.30')\n",
"(327, 'Damjan Rudez', '-1.31')\n",
"(328, 'Andre Miller', '-1.32')\n",
"(329, 'Will Cherry', '-1.33')\n",
"(330, 'Andrea Bargnani', '-1.33')\n",
"(331, 'Victor Oladipo', '-1.34')\n",
"(332, 'Marco Belinelli', '-1.35')\n",
"(333, 'D.J. Augustin', '-1.35')\n",
"(334, 'Troy Daniels', '-1.35')\n",
"(335, 'Markel Brown', '-1.36')\n",
"(336, 'Kevin Seraphin', '-1.40')\n",
"(337, 'Elton Brand', '-1.44')\n",
"(338, 'Isaiah Canaan', '-1.50')\n",
"(339, 'Erick Green', '-1.50')\n",
"(340, 'Darrell Arthur', '-1.51')\n",
"(341, 'Lance Stephenson', '-1.51')\n",
"(342, 'Derrick Favors', '-1.52')\n",
"(343, 'Greivis Vasquez', '-1.54')\n",
"(344, 'Andrew Nicholson', '-1.55')\n",
"(345, 'J.J. Hickson', '-1.55')\n",
"(346, 'Steve Novak', '-1.55')\n",
"(347, 'Jakarr Sampson', '-1.58')\n",
"(348, 'Anderson Varejao', '-1.60')\n",
"(349, 'Jorge Gutierrez', '-1.62')\n",
"(350, \"Johnny O'Bryant\", '-1.63')\n",
"(351, 'Adreian Payne', '-1.65')\n",
"(352, 'Carl Landry', '-1.65')\n",
"(353, 'Shabazz Napier', '-1.66')\n",
"(354, 'Ish Smith', '-1.66')\n",
"(355, 'Shawne Williams', '-1.67')\n",
"(356, 'Ian Mahinmi', '-1.68')\n",
"(357, 'Nick Collison', '-1.70')\n",
"(358, 'Alec Burks', '-1.73')\n",
"(359, 'Andrei Kirilenko', '-1.73')\n",
"(360, 'Elijah Millsap', '-1.74')\n",
"(361, 'John Jenkins', '-1.76')\n",
"(362, 'Brandan Wright', '-1.77')\n",
"(363, 'A.J. Price', '-1.81')\n",
"(364, 'Jodie Meeks', '-1.84')\n",
"(365, 'Patrick Christopher', '-1.88')\n",
"(366, 'Vince Carter', '-1.90')\n",
"(367, 'Patrick Beverley', '-1.97')\n",
"(368, 'Sergey Karasev', '-1.98')\n",
"(369, 'Kyle Anderson', '-2.01')\n",
"(370, 'Cleanthony Early', '-2.02')\n",
"(371, 'Cartier Martin', '-2.05')\n",
"(372, 'Nik Stauskas', '-2.06')\n",
"(373, 'Grant Jerrett', '-2.07')\n",
"(374, 'Jeffery Taylor', '-2.10')\n",
"(375, 'Solomon Hill', '-2.15')\n",
"(376, 'Jeremy Lamb', '-2.16')\n",
"(377, 'Tony Wroten', '-2.20')\n",
"(378, 'Greg Smith', '-2.20')\n",
"(379, 'Dahntay Jones', '-2.21')\n",
"(380, 'Ryan Hollins', '-2.24')\n",
"(381, 'Alonzo Gee', '-2.24')\n",
"(382, 'Brandon Bass', '-2.24')\n",
"(383, 'Sebastian Telfair', '-2.27')\n",
"(384, 'Furkan Aldemir', '-2.28')\n",
"(385, 'Martell Webster', '-2.32')\n",
"(386, 'Austin Daye', '-2.34')\n",
"(387, 'Terrence Ross', '-2.35')\n",
"(388, 'JaVale McGee', '-2.38')\n",
"(389, 'Rodney Stuckey', '-2.39')\n",
"(390, 'James Jones', '-2.48')\n",
"(391, 'Joe Harris', '-2.55')\n",
"(392, 'Jordan Farmar', '-2.56')\n",
"(393, 'Tim Hardaway Jr.', '-2.59')\n",
"(394, 'Kobe Bryant', '-2.60')\n",
"(395, 'Spencer Dinwiddie', '-2.60')\n",
"(396, 'Justin Hamilton', '-2.62')\n",
"(397, 'Lance Thomas', '-2.62')\n",
"(398, 'Brook Lopez', '-2.64')\n",
"(399, 'Ersan Ilyasova', '-2.67')\n",
"(400, 'Jose Calderon', '-2.68')\n",
"(401, 'Jordan Clarkson', '-2.68')\n",
"(402, \"Kyle O'Quinn\", '-2.69')\n",
"(403, 'Landry Fields', '-2.74')\n",
"(404, 'Jon Leuer', '-2.75')\n",
"(405, 'Cole Aldrich', '-2.80')\n",
"(406, 'Aaron Gordon', '-2.80')\n",
"(407, 'Alexey Shved', '-2.81')\n",
"(408, 'Gary Neal', '-2.88')\n",
"(409, 'Norris Cole', '-2.96')\n",
"(410, 'Jerome Jordan', '-2.98')\n",
"(411, 'Gorgui Dieng', '-3.00')\n",
"(412, 'Nicolas Batum', '-3.02')\n",
"(413, 'Matthew Dellavedova', '-3.02')\n",
"(414, 'Raymond Felton', '-3.03')\n",
"(415, 'Brendan Haywood', '-3.05')\n",
"(416, 'Nate Robinson', '-3.07')\n",
"(417, 'Spencer Hawes', '-3.08')\n",
"(418, 'Wilson Chandler', '-3.14')\n",
"(419, 'Archie Goodwin', '-3.27')\n",
"(420, 'Larry Drew II', '-3.31')\n",
"(421, 'Quincy Pondexter', '-3.31')\n",
"(422, 'Chase Budinger', '-3.31')\n",
"(423, 'Josh Smith', '-3.33')\n",
"(424, 'Tarik Black', '-3.35')\n",
"(425, 'Udonis Haslem', '-3.37')\n",
"(426, 'Evan Turner', '-3.38')\n",
"(427, 'Jameer Nelson', '-3.39')\n",
"(428, 'Ben Gordon', '-3.56')\n",
"(429, 'Brandon Rush', '-3.57')\n",
"(430, 'Perry Jones', '-3.60')\n",
"(431, 'Hollis Thompson', '-3.60')\n",
"(432, 'Channing Frye', '-3.63')\n",
"(433, 'Austin Rivers', '-3.68')\n",
"(434, 'Danny Granger', '-3.71')\n",
"(435, 'Festus Ezeli', '-3.71')\n",
"(436, 'Ian Clark', '-3.74')\n",
"(437, 'Jordan Hill', '-3.78')\n",
"(438, 'John Salmons', '-3.86')\n",
"(439, 'Dennis Schroder', '-3.97')\n",
"(440, 'Luke Babbitt', '-4.02')\n",
"(441, 'Brandon Knight', '-4.03')\n",
"(442, 'Shaun Livingston', '-4.10')\n",
"(443, 'Tony Parker', '-4.10')\n",
"(444, 'Malcolm Thomas', '-4.19')\n",
"(445, 'Ramon Sessions', '-4.20')\n",
"(446, 'Dion Waiters', '-4.21')\n",
"(447, 'Joe Ingles', '-4.23')\n",
"(448, 'Chris Kaman', '-4.27')\n",
"(449, 'Jonas Valanciunas', '-4.49')\n",
"(450, 'Leandro Barbosa', '-4.58')\n",
"(451, 'Luke Ridnour', '-4.60')\n",
"(452, 'Kris Humphries', '-4.60')\n",
"(453, 'Darius Morris', '-4.61')\n",
"(454, 'Doug McDermott', '-4.61')\n",
"(455, 'Jabari Parker', '-4.76')\n",
"(456, 'Al Jefferson', '-4.81')\n",
"(457, 'Nerlens Noel', '-4.90')\n",
"(458, 'Samuel Dalembert', '-4.98')\n",
"(459, 'Brandon Davies', '-5.05')\n",
"(460, 'Jeff Green', '-5.18')\n",
"(461, 'Jason Thompson', '-5.24')\n",
"(462, 'Kent Bazemore', '-5.24')\n",
"(463, 'Jarrett Jack', '-5.38')\n",
"(464, 'Ray McCallum', '-5.45')\n",
"(465, 'Omri Casspi', '-5.57')\n",
"(466, 'Anthony Bennett', '-6.33')\n",
"(467, 'Derrick Williams', '-6.80')\n",
"(468, 'Shane Larkin', '-6.93')\n",
"(469, 'Zach LaVine', '-7.64')\n",
"(470, 'Jason Smith', '-9.59')\n"
]
}
],
"prompt_number": 396
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment