特定の選手のスタッツを取得する方法
選手のスタッツ情報とはbasketball-referenceで言うとコチラに当たります
www.basketball-reference.com
コチラのチュートリアルを参考にしました
github.com
# Jayson Tatumのキャリアスタッツを見る方法 from nba_api.stats.static import players player_id = None for _ in players.get_active_players(): if _['full_name'] == 'James Harden': player_id = _['id'] from nba_api.stats.endpoints import playercareerstats career = playercareerstats.PlayerCareerStats(player_id) # 各種シーズンのスタッツが見れる print(career.get_normalized_dict().keys()) # dict_keys(['SeasonTotalsRegularSeason', 'CareerTotalsRegularSeason', 'SeasonTotalsPostSeason', 'CareerTotalsPostSeason', 'SeasonTotalsAllStarSeason', 'CareerTotalsAllStarSeason', 'SeasonTotalsCollegeSeason', 'CareerTotalsCollegeSeason', 'SeasonRankingsRegularSeason', 'SeasonRankingsPostSeason']) # SeasonTotalsRegularSeasonのスタッツ print(career.get_data_frames()[0]) # PLAYER_ID SEASON_ID LEAGUE_ID TEAM_ID TEAM_ABBREVIATION PLAYER_AGE GP GS MIN FGM FGA FG_PCT FG3M FG3A FG3_PCT FTM FTA FT_PCT OREB DREB REB AST STL BLK TOV PF PTS # 0 201935 2009-10 00 1610612760 OKC 20.0 76 0 1738.0 233 578 0.403 93 248 0.375 194 240 0.808 47 197 244 137 80 20 106 200 753 # 1 201935 2010-11 00 1610612760 OKC 21.0 82 5 2189.0 298 684 0.436 113 324 0.349 289 343 0.843 42 213 255 176 92 24 106 207 998 # 2 201935 2011-12 00 1610612760 OKC 22.0 62 2 1946.0 309 629 0.491 114 292 0.390 312 369 0.846 30 222 252 229 62 15 137 150 1044 # 3 201935 2012-13 00 1610612745 HOU 23.0 78 78 2985.0 585 1337 0.438 179 486 0.368 674 792 0.851 62 317 379 455 142 38 295 178 2023 # 4 201935 2013-14 00 1610612745 HOU 24.0 73 73 2777.0 549 1205 0.456 177 483 0.366 576 665 0.866 61 283 344 446 115 29 265 177 1851 # 5 201935 2014-15 00 1610612745 HOU 25.0 81 81 2981.0 647 1470 0.440 208 555 0.375 715 824 0.868 75 384 459 565 154 60 321 208 2217 # 6 201935 2015-16 00 1610612745 HOU 26.0 82 82 3125.0 710 1617 0.439 236 657 0.359 720 837 0.860 63 438 501 612 139 51 374 229 2376 # 7 201935 2016-17 00 1610612745 HOU 27.0 81 81 2947.0 674 1533 0.440 262 756 0.347 746 881 0.847 95 564 659 907 121 38 464 215 2356 # 8 201935 2017-18 00 1610612745 HOU 28.0 72 72 2551.0 651 1449 0.449 265 722 0.367 624 727 0.858 41 348 389 630 126 50 315 169 2191 # 9 201935 2018-19 00 1610612745 HOU 29.0 78 78 2867.0 843 1909 0.442 378 1028 0.368 754 858 0.879 66 452 518 586 158 58 387 244 2818 # 10 201935 2019-20 00 1610612745 HOU 30.0 68 68 2483.0 672 1514 0.444 299 843 0.355 692 800 0.865 70 376 446 512 125 60 308 227 2335 # 11 201935 2020-21 00 1610612745 HOU 31.0 8 8 290.0 60 135 0.444 25 72 0.347 53 60 0.883 5 36 41 83 7 6 34 14 198 # 12 201935 2020-21 00 1610612751 BKN 31.0 36 35 1319.0 282 599 0.471 96 262 0.366 225 263 0.856 30 277 307 392 46 27 143 85 885 # 13 201935 2020-21 00 0 TOT 31.0 44 43 1609.0 342 734 0.466 121 334 0.362 278 323 0.861 35 313 348 475 53 33 177 99 1083
特定の試合を検索する方法
コチラのチュートリアルをpythonベースで書き直しました
github.com
ipythonの方がSQLのような操作ができるため、チュートリアル通りにやったほうが良いかもしれませんが……
from dataclasses import dataclass from typing import List, Dict, Tuple, Set, Any, Optional # 1つの試合を見つけるには、LeagueGameFinderクラスを使います。 # 引数なしで呼び出すことができ、NBA、WNBA、Gリーグ、国際球の中から約30,000試合 # (nba.comがレスポンスで送信する最大行数だと思います)が返されますが、 # チームIDを渡した方が良いでしょう。 # 2017-18 シーズンのCeltics vs Raptorsの最後に対戦した試合 # 1. Fetch all Celtics games # 2. 2017-18のゲームに絞る # 3. 対戦相手がラプターズであるゲームに絞る # 4. 日付順に並べ最後の行を選択する @dataclass class Team: id: int full_name: str abbreviation: str nickname: str city: str state: str year_founded: int @dataclass class Game: SEASON_ID: str TEAM_ID: str TEAM_ABBREVIATION: str TEAM_NAME: int GAME_ID: str GAME_DATE: str MATCHUP: str WL: str MIN: int PTS: int FGM: int FGA: int FG_PCT: float FG3M: int FG3A: int FG3_PCT: float FTM: int FTA: int FT_PCT: float OREB: int DREB: int REB: int AST: int STL: int BLK: int TOV: int PF: int PLUS_MINUS: float # 1. Fetch all Celtics games # 1.1 Get Celtics team_id from nba_api.stats.static import teams nba_teams: List[Team] = [] for i, _ in enumerate(teams.get_teams()): team = Team(**_) nba_teams.append(team) bucks_id = [_ for _ in nba_teams if _.abbreviation == 'MIL'][0].id # 1.2 Fetch all Celtics games from nba_api.stats.endpoints import leaguegamefinder gamefinder = leaguegamefinder.LeagueGameFinder(team_id_nullable=bucks_id) games_ = gamefinder.get_normalized_dict() games: List[Game] = [] for _ in games_['LeagueGameFinderResults']: game = Game(**_) games.append(game) # 2. 2020-21のゲームに絞る # ※シーズンIDはテーブル見ないと分からないかも? bucks_games = [_ for _ in games if _.SEASON_ID == '42020'] # 3. NETSとの対戦に絞る vs_nets_games = [_ for _ in bucks_games if 'BKN' in _.MATCHUP] # 4. 最新の試合を取得する(最初のインデックス) print(vs_nets_games[0]) # Game(SEASON_ID='42020', TEAM_ID=1610612749, TEAM_ABBREVIATION='MIL', TEAM_NAME='Milwaukee Bucks', GAME_ID='0042000217', GAME_DATE='2021-06-19', MATCHUP='MIL @ BKN', WL='W', MIN=263, PTS=115, FGM=43, FGA=98, FG_PCT=0.439, FG3M=15, FG3A=36, FG3_PCT=0.417, FTM=14, FTA=21, FT_PCT=0.667, OREB=18, DREB=30, REB=48, AST=20, STL=9, BLK=7, TOV=7, PF=20, PLUS_MINUS=4.0)
試合に関する情報を取得する方法
試合の情報とはbasketball-referenceで言うとコチラのページに該当します
www.basketball-reference.com
コチラのチュートリアルをpythonベースで書き直しました
github.com
試合に関する情報とは主に
- 試合の基本情報
- 日程
- マッチアップ
- BoxScore
- Play-by-Play
- ShotChart
from dataclasses import dataclass from typing import Dict, List, Tuple, Any, Set @dataclass class Team: id: int full_name: str abbreviation: str nickname: str city: str state: str year_founded: int @dataclass class Game: SEASON_ID: str TEAM_ID: str TEAM_ABBREVIATION: str TEAM_NAME: int GAME_ID: str GAME_DATE: str MATCHUP: str WL: str MIN: int PTS: int FGM: int FGA: int FG_PCT: float FG3M: int FG3A: int FG3_PCT: float FTM: int FTA: int FT_PCT: float OREB: int DREB: int REB: int AST: int STL: int BLK: int TOV: int PF: int PLUS_MINUS: float # チームIDの取得 from nba_api.stats.static import teams # 30チームを取得 nba_teams = teams.get_teams() teams_by_abbreviation: Dict[str, Team] = dict() for nba_team in nba_teams: team = Team(**nba_team) teams_by_abbreviation[team.abbreviation] = team # ペイサーズのIDを見つける pacers_id = teams_by_abbreviation['IND'].id # 最新のレギュラーシーズンのペイサーズの情報 from nba_api.stats.endpoints import leaguegamefinder from nba_api.stats.library.parameters import Season from nba_api.stats.library.parameters import SeasonType gamefinder = leaguegamefinder.LeagueGameFinder(team_id_nullable=pacers_id, season_nullable=Season.default, # 2020-21 season_type_nullable=SeasonType.regular # Regular Season ) games_dict : Dict[str, List[Dict[Any, Any]]] = gamefinder.get_normalized_dict() games: List[Game] = [] for game_ in games_dict['LeagueGameFinderResults']: game = Game(**game_) games.append(game) print(games[0]) # Game(SEASON_ID='22020', TEAM_ID=1610612754, TEAM_ABBREVIATION='IND', TEAM_NAME='Indiana Pacers', GAME_ID='0022001079', GAME_DATE='2021-05-16', MATCHUP='IND @ TOR', WL='W', MIN=239, PTS=125, FGM=48, FGA=95, FG_PCT=0.505, FG3M=15, FG3A=37, FG3_PCT=0.405, FTM=14, FTA=18, FT_PCT=0.778, OREB=10, DREB=37, REB=47, AST=34, STL=8, BLK=3, TOV=13, PF=19, PLUS_MINUS=12.0)
全試合で最もPTSが高かったゲームを求める
gamefinder = leaguegamefinder.LeagueGameFinder(season_type_nullable=SeasonType.regular) # Regular Season games_dict : Dict[str, List[Dict[Any, Any]]] = gamefinder.get_normalized_dict() # 2020-21のレギュラーシーズンの全試合 games: List[Game] = [] for game_ in games_dict['LeagueGameFinderResults']: game = Game(**game_) games.append(game) games.sort(key=lambda g: g.PTS, reverse=True) print(games[0]) # Game(SEASON_ID='22014', TEAM_ID=1612709905, TEAM_ABBREVIATION='LAD', TEAM_NAME='Los Angeles D-Fenders', GAME_ID='2021400117', GAME_DATE='2014-12-20', MATCHUP='LAD vs. RNO', WL='W', MIN=241, PTS=175, FGM=69, FGA=112, FG_PCT=0.616, FG3M=11, FG3A=21, FG3_PCT=0.524, FTM=26, FTA=35, FT_PCT=0.743, OREB=18, DREB=45, REB=63, AST=48, STL=8, BLK=5, TOV=24, PF=26, PLUS_MINUS=23.0)
特定の試合のPlay-by-Playデータを見る
@dataclass class PlayByPlay: GAME_ID: int EVENTNUM: int EVENTMSGTYPE: int EVENTMSGACTIONTYPE: int PERIOD: int WCTIMESTRING: str PCTIMESTRING: str HOMEDESCRIPTION: Optional[str] NEUTRALDESCRIPTION: str VISITORDESCRIPTION: Optional[str] SCORE: str SCOREMARGIN: int from nba_api.stats.endpoints import playbyplay game_id = games[0].GAME_ID play_by_play_dict: Dict[str, List[Dict[str, Any]]] = playbyplay.PlayByPlay(game_id).get_normalized_dict() play_by_plays: List[PlayByPlay] = [] for _ in play_by_play_dict['PlayByPlay']: pbp = PlayByPlay(**_) play_by_plays.append(pbp) # HOMEDESCRIPTIONはHOMEチームのイベント説明 # VISITORDESCRIPTIONはVISITORチームのイベントの説明 # NEUTRALDESCRIPTIONはクォーターの始まりと終わり for pbp in play_by_plays: if pbp.SCORE: print(f'{pbp.SCORE} | {pbp.HOMEDESCRIPTION} | {pbp.VISITORDESCRIPTION}') print(pbp.SCORE, pbp.HOMEDESCRIPTION, pbp.VISITORDESCRIPTION) if pbp.NEUTRALDESCRIPTION: if pbp.NEUTRALDESCRIPTION.startswith('Start'): print('-'*60) print(pbp.NEUTRALDESCRIPTION) if pbp.NEUTRALDESCRIPTION.startswith('End'): print(pbp.NEUTRALDESCRIPTION) print('-'*60) # ------------------------------------------------------------ # Start of 1st Period (8:11 PM EST) # 2 - 0 | None | Brissett 12' Driving Floating Jump Shot (2 PTS) (Sabonis 1 AST) # 2 - 0 None Brissett 12' Driving Floating Jump Shot (2 PTS) (Sabonis 1 AST) # 4 - 0 | None | Sumner 2' Cutting Layup Shot (2 PTS) (Sabonis 2 AST) # 4 - 0 None Sumner 2' Cutting Layup Shot (2 PTS) (Sabonis 2 AST) # 6 - 0 | None | Sumner 1' Driving Layup (4 PTS) (Sabonis 3 AST) # 6 - 0 None Sumner 1' Driving Layup (4 PTS) (Sabonis 3 AST) # 得点の推移のみを見る from enum import Enum class EventMsgType(Enum): FIELD_GOAL_MADE = 1 FIELD_GOAL_MISSED = 2 FREE_THROWfree_throw_attempt = 3 REBOUND = 4 TURNOVER = 5 FOUL = 6 VIOLATION = 7 SUBSTITUTION = 8 TIMEOUT = 9 JUMP_BALL = 10 EJECTION = 11 PERIOD_BEGIN = 12 PERIOD_END = 13 for pbp in play_by_plays: if pbp.EVENTMSGTYPE == EventMsgType.FIELD_GOAL_MADE.value: print(pbp.SCORE) # 2 - 0 # 4 - 0 # 6 - 0 # 8 - 0 # 10 - 2 # 11 - 4
ある試合のbox_scoreを閲覧する方法
# boxscoreについて @dataclass class BoxScore: GAME_ID: str TEAM_ID: str TEAM_ABBREVIATION: str TEAM_CITY: str PLAYER_ID: str PLAYER_NAME: str NICKNAME: str START_POSITION: str COMMENT: str MIN: str PCT_FGA_2PT: str PCT_FGA_3PT: str PCT_PTS_2PT: str PCT_PTS_2PT_MR: str PCT_PTS_3PT: str PCT_PTS_FB: str PCT_PTS_FT: str PCT_PTS_OFF_TOV: str PCT_PTS_PAINT: str PCT_AST_2PM: str PCT_UAST_2PM: str PCT_AST_3PM: str PCT_UAST_3PM: str PCT_AST_FGM: str PCT_UAST_FGM: str from nba_api.stats.endpoints import boxscorescoringv2 box_score_dict: Dict[str, List[Dict[str, Any]]] = boxscorescoringv2.BoxScoreScoringV2(game_id).get_normalized_dict() box_scores: List[BoxScore] = [] for _ in box_score_dict['sqlPlayersScoring']: box_score = BoxScore(**_) box_scores.append(box_score) print(box_scores[0]) # BoxScore(GAME_ID='0022000963', TEAM_ID=1610612754, TEAM_ABBREVIATION='IND', TEAM_CITY='Indiana', PLAYER_ID=203926, PLAYER_NAME='Doug McDermott', NICKNAME='Doug', START_POSITION='F', COMMENT='', MIN='26:59', PCT_FGA_2PT=0.429, PCT_FGA_3PT=0.571, PCT_PTS_2PT=0.323, PCT_PTS_2PT_MR=0.0, PCT_PTS_3PT=0.581, PCT_PTS_FB=0.097, PCT_PTS_FT=0.097, PCT_PTS_OFF_TOV=0.161, PCT_PTS_PAINT=0.323, PCT_AST_2PM=1.0, PCT_UAST_2PM=0.0, PCT_AST_3PM=1.0, PCT_UAST_3PM=0.0, PCT_AST_FGM=1.0, PCT_UAST_FGM=0.0)
ある試合のある選手のショットチャートを閲覧する方法
ショットチャートの検索にはキーとしてteam_id, player_idが必要だったので、roster検索でgame_idからplayer_idを探しています
続いて、APIで得られたショットチャートの結果から特定の試合game_idの結果のみを表示しています
# Shot Chartについて # Rosterから選手IDを取得 from nba_api.stats.endpoints import commonteamroster player_id = None team_id = games[0].TEAM_ID commonteamroster_dict = commonteamroster.CommonTeamRoster(team_id).get_normalized_dict() for _ in commonteamroster_dict['CommonTeamRoster']: if _['PLAYER'] == 'Domantas Sabonis': player_id = _['PLAYER_ID'] # Shot Chart from nba_api.stats.endpoints import shotchartdetail shot_chart_detail_dict: Dict[str, List[Dict[str, Any]]] = shotchartdetail.ShotChartDetail(team_id, player_id).get_normalized_dict() # print(shot_chart_detail_dict.keys()) # dict_keys(['Shot_Chart_Detail', 'LeagueAverages']) for _ in shot_chart_detail_dict['Shot_Chart_Detail']: if _['GAME_ID'] == games[0].GAME_ID: print(_['SHOT_TYPE'], _['SHOT_ZONE_BASIC'], _['SHOT_ZONE_AREA'], _['SHOT_ZONE_RANGE'], _['SHOT_DISTANCE']) # 2PT Field Goal Restricted Area Center(C) Less Than 8 ft. 2 # 2PT Field Goal Restricted Area Center(C) Less Than 8 ft. 1 # 3PT Field Goal Above the Break 3 Left Side Center(LC) 24+ ft. 25 # 2PT Field Goal Restricted Area Center(C) Less Than 8 ft. 1 # 2PT Field Goal Restricted Area Center(C) Less Than 8 ft. 1 # 3PT Field Goal Above the Break 3 Right Side Center(RC) 24+ ft. 25 # 2PT Field Goal Restricted Area Center(C) Less Than 8 ft. 2 # 2PT Field Goal Restricted Area Center(C) Less Than 8 ft. 1 # 2PT Field Goal Restricted Area Center(C) Less Than 8 ft. 1 # 2PT Field Goal Restricted Area Center(C) Less Than 8 ft. 1