<jupyter_start><jupyter_text>6 - NBA Player DetailNow we're going to heavily use the [nba_api](https://github.com/swar/nba_api) data library as it's proven to be a great API for extracting data from https://stats.nba.com.<jupyter_code># %pip install nba_api
import utils
import pandas as pd
import pathlib
from nba_api.stats.endpoints import commonplayerinfo, playercareerstats
from nba_api.stats.static import players
BASE_DIR = pathlib.Path().resolve()
SAMPLES_DIR = BASE_DIR / 'samples'
SAMPLE_PLAYERS_DIR = SAMPLES_DIR / 'players'
SAMPLE_PLAYERS_DIR.mkdir(exist_ok=True, parents=True)
salary_df = pd.read_csv('samples/5-player-adj-salaries-audit.csv')
salary_df.columns = [f"{x}".upper() for x in salary_df.columns]<jupyter_output><empty_output><jupyter_text>I converted our columns to match the column names in the `nba_api` library.<jupyter_code>random_row = salary_df.sample(n=1)
name = random_row['PLAYER'].item() # .item() will get the value
random_row<jupyter_output><empty_output><jupyter_text>Using `.sample(n=1)` will return a random sample of our data. This sample can be as large as you'd like but I chose to return `1` row (`n=1`) to ultimately get `1` player's name for use in the API.<jupyter_code># name = '<NAME>'
name
player_results = players.find_players_by_full_name(name) 
player_df = pd.DataFrame(player_results)
player_df.head()
player_df
player_id = player_df.iloc[0]['id'].item()
# player_id = player_df.loc[0]['id'].item()<jupyter_output><empty_output><jupyter_text>`.iloc` is much like using an index value in a standard python list. `iloc[23]` will yield the 24th element in the DataFrame. `iloc[0]` will return the 1st element at the 0th position. `loc[0]` *may* yield the same result if the index column is not shuffled.<jupyter_code>career = playercareerstats.PlayerCareerStats(player_id=player_id)
career_df = career.get_data_frames()[0]
career_df.head()
def season_id_to_season_end(val):
    season_start, season_end = val.split("-")
    if f"{season_start}".startswith("1"):
        season_end = f"19{season_end}"
    else:
        season_end = f"20{season_end}"
    return season_end
career_df['YEAR_START'] = career_df['SEASON_ID'].apply(lambda x: x.split("-")[0])
career_df['YEAR_END'] = career_df['SEASON_ID'].apply(season_id_to_season_end)
career_df.head()
year_start = career_df['YEAR_START'].min()
year_end = career_df['YEAR_END'].max()
year_start, year_end
key_stats = ['GP',
 'GS',
 'MIN',
 'FGM',
 'FGA',
 'FG_PCT',
 'FG3M',
 'FG3A',
 'FG3_PCT',
 'FTM',
 'FTA',
 'FT_PCT',
 'OREB',
 'DREB',
 'REB',
 'AST',
 'STL',
 'BLK',
 'TOV',
 'PF',
 'PTS']
    
key_stats_labels = [
    "Games Played",
    "Games Started",
    "Minutes",
    "Field Goals Made",
    "Field Goals Attempted",
    "Field Goal Percentage",
    "3-point Field Goals Made",
    "3-point Field Goals Made Attempted",
    "3-point Field Goal Percentage",
    'Free Throws Made',
    'Free Throws Attempted',
    'Free Throw Percentage',
    'Offensive Rebouns',
    'Defensive Rebouns',
    'Rebouns',
    'Assists',
    'Steals',
    'Blocks',
    'Turnovers',
    'Personal Fouls',
    'Points'
]
   
key_stats_mapping = dict(zip(key_stats, key_stats_labels))
stats_without_perc = [x for x in key_stats if not "pct" in x.lower()]
stats_with_perc = [x for x in key_stats if "pct" in x.lower()]
career_df
career_stats_columns = stats_without_perc + ["SEASON_ID"]
career_stats = career_df.copy()[career_stats_columns]
career_stats.head()
# career_stats = career_stats.astype(int)
career_stats.set_index("SEASON_ID", inplace=True, drop=True)
totals_df = career_stats.rename(columns=key_stats_mapping)
totals = totals_df.sum()
totals_df
career_stats_perc = career_df.copy()[stats_with_perc]
averages_df = career_stats_perc.rename(columns=key_stats_mapping)
averages = averages_df.mean()
totals
averages
earnings = salary_df.copy()[salary_df['PLAYER'] == name][['SALARY', 'ADJ_SALARY', 'YEAR_START']]
earnings.set_index("YEAR_START", inplace=True, drop=True)
earnings.tail(n=15)
total_earnings = earnings.sum().apply(utils.float_to_dollars)
total_earnings
name
total_games = career_stats.GP.sum()
total_games
earnings_per_game = earnings['SALARY'].sum() / total_games
utils.float_to_dollars(earnings_per_game)
plot = earnings.plot()<jupyter_output><empty_output><jupyter_text>Export Player Data<jupyter_code>PLAYER_DIR = SAMPLE_PLAYERS_DIR / f"{name}"
PLAYER_DIR.mkdir(exist_ok=True, parents=True)
# Eearnings Plot
figure = plot.figure
figure.savefig(PLAYER_DIR / f"salary_over_time.png")
stats_output = PLAYER_DIR / "stats.xlsx"
totals_df
with pd.ExcelWriter(stats_output) as writer:
    totals_df.to_excel(writer, sheet_name='Career Stats')
    totals.to_excel(writer, sheet_name='Career Totals')
    averages.to_excel(writer, sheet_name='Career Averages')
    earnings.to_excel(writer, sheet_name='Yearly Earnings')
    total_earnings.to_excel(writer, sheet_name='Total Earnings')
name
import requests
import requests

url = "https://stats.nba.com/stats/playerindex?College=&Country=&DraftPick=&DraftRound=&DraftYear=&Height=&Historical=1&LeagueID=00&Season=2021-22&SeasonType=Regular%20Season&TeamID=0"
url = "https://stats.nba.com/stats/playercareerstats?LeagueID=&PerMode=Totals&PlayerID=2544"

r = requests.get(url, stream=True)
r.json()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13458262350936967, 'fraction_numerical': 0.009085746734809767, 'mean_word_length': 6.09261744966443, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 22, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '340114', 'license': 'MIT', 'n_tokens_mistral': 2040, 'n_tokens_neox': 1972, 'n_words': 400, 'path': 'course/appendix/Appendix D - NBA Player Detail.ipynb', 'repo_name': 'cmg777/Try-Pandas', 'size': '5291'}