This brief tutorial shows how you can use the Hoopsville package to create custom video playlists on If you have any questions or feedback, find me on Twitter.

As someone who’s trying to learn about basketball, I’m fortunate that there are a lot of #content* out there that I can lean on to get a better understanding about all areas of the sport.

For example, Zach Lowe’s weekly Ten Things pieces have taught me a lot, as has his Lowe Post podcast. My favourite place to read/watch/learn about basketball though is Cleaning The Glass. It’s a subscription based website, but you get stats, in-depth articles and a discussion forum for a measly $5 a month.

(*I’m not going to list loads of links in this post, but if you want to learn more about the NBA and find out what to read/watch/listen to and who to follow then you won’t find a more in depth list than the r/NBA “PhD Program” here.)

One of the main ways to learn about a sport is to actually watch the games (duh) but to do this you need video. Footage of full games can be easily found online - if you know where to look - but these are usually a few gigabytes in size and not always what you want when focusing on a specific facet of a given player or team’s play.

YouTube highlight channels showcase the made buckets and big moments of every game, but again these are never tailored to a specific player (unless they’ve had a noteworthy game).

Using my Hoopsville python package and I’m going to show how you can create custom playlists. Don’t worry if you don’t have any Python experience, I’ll post the files you need online (skip to the files here).

Finding the Video

Thanks to Ben Falk (founder of the aforementioned Cleaning The Glass site) I was pointed in the direction of this page on the site, after asking Ben how he finds footage efficiently for his articles.

It’s part of the site that allows you to query any player/team/game and watch the video of their on ball events (think assists, rebounds, field goal attempts, etc.). Quite a powerful tool, which I’m fortunate to have access to a similar sort of thing for football in my day job.

To change the playlist, you just need to change out the separate parts of the following URL:

The parameters that can be changed in the URL are:

  • PlayerID - 204001 here is Kristaps Porzingis
  • TeamID - 1610612752 here is the New York Knicks
  • GameID - 0021700550 here is the game between the New York Knicks and the San Antonio Spurs
  • ContextMeasure - FGA here is Field Goal Attempts (i.e. all 2 or 3 point shots)
  • Season - 2017-18 here is the current 17/18 season

There are a couple more that could be tweaked, but these aren’t relevant right now.

Pulling the Data

This link is great if you’re really interested in looking at Porzingis’ shot attempts, but pointless if you want to look at Chris Paul’s season high 14 assists against the Brooklyn Nets back in November.

To get a playlist of Paul’s assists I need his PlayerID and GameID. To grab both of these things, I’ll use the Hoopsville package. First, I’ll get Paul’s PlayerID.

After installing the Hoopsville package, fire up iPython and import the package:

import hoopsville as hv

You can then get a pandas DataFrame of all of the players who’ve played in the league this season by running:

players = hv.get_players()

The first few rows and columns of the players DataFrame looks like this:

players.iloc[0:4, 0:7].set_index('PERSON_ID')

203518 Abrines, Alex Alex Abrines 1 2016 2017 alex_abrines
203112 Acy, Quincy Quincy Acy 1 2012 2017 quincy_acy
203500 Adams, Steven Steven Adams 1 2013 2017 steven_adams
1628389 Adebayo, Bam Bam Adebayo 1 2017 2017 bam_adebayo
201167 Afflalo, Arron Arron Afflalo 1 2007 2017 arron_afflalo

I shortened this down so that it’d fit properly on the page, but this is the only information that is needed to continue.

The PLAYERCODE here looks to be the combination of a player’s first name, an underscore and their last name. In order to get Chris Paul’s data I should only have to filter down the DataFrame just using chris_paul.

First I’ll store the filtered down DataFrame containing just Paul’s PLAYERCODE:

cp3 = players.loc[players.PLAYERCODE == 'chris_paul']

Next I’ll take a look at the table, again just taking the first seven columns:

cp3.iloc[:, 0:7].set_index('PERSON_ID')

101108 Paul, Chris Chris Paul 1 2005 2017 chris_paul

Perfect, Paul’s PERSON_ID is 101108. Now all that’s needed is the Game_ID for the game against the Nets.

Using the get_teams() function in Hoopsville I can quickly look up what the Houston Rockets Team_ID is:


1610612737 ATL
1610612738 BOS
1610612739 CLE
1610612740 NOP
1610612741 CHI
1610612742 DAL
1610612743 DEN
1610612744 GSW
1610612745 HOU
1610612746 LAC

The Team_ID for Rockets is 1610612745. I can then plug this into the get_team_games function to get data on their games this season:

HOU = hv.get_team_games(tid=1610612745)

Again, I’ll use a shortened version of the DataFrame:


1610612745 0021700294 NOV 27, 2017 HOU vs. BKN

Getting The Video

Now that I have Paul’s Player_ID and Game_ID I can plug them into the URL used previously to get his assists vs the Nets. Note I also changed the ContextMeasure to AST to just get the footage on his assists:

It works! Now you can repeat the same process for any player, team or game in the past few seasons.

Player and Game data dumps

Player data can be found here.

Game data can be found here.