nbastatpy 0.1.6__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nbastatpy might be problematic. Click here for more details.
- nbastatpy/__init__.py +17 -1
- nbastatpy/config.py +445 -0
- nbastatpy/game.py +131 -30
- nbastatpy/player.py +58 -22
- nbastatpy/season.py +272 -50
- nbastatpy/standardize.py +529 -0
- nbastatpy/team.py +49 -16
- nbastatpy/utils.py +30 -3
- nbastatpy/validators.py +288 -0
- nbastatpy-0.2.0.dist-info/METADATA +69 -0
- nbastatpy-0.2.0.dist-info/RECORD +14 -0
- {nbastatpy-0.1.6.dist-info → nbastatpy-0.2.0.dist-info}/WHEEL +2 -1
- nbastatpy-0.2.0.dist-info/top_level.txt +1 -0
- nbastatpy-0.1.6.dist-info/METADATA +0 -67
- nbastatpy-0.1.6.dist-info/RECORD +0 -10
- {nbastatpy-0.1.6.dist-info → nbastatpy-0.2.0.dist-info/licenses}/LICENSE +0 -0
nbastatpy/game.py
CHANGED
|
@@ -3,6 +3,7 @@ from typing import List
|
|
|
3
3
|
import nba_api.stats.endpoints as nba
|
|
4
4
|
import pandas as pd
|
|
5
5
|
|
|
6
|
+
from nbastatpy.standardize import standardize_dataframe
|
|
6
7
|
from nbastatpy.utils import Formatter
|
|
7
8
|
|
|
8
9
|
|
|
@@ -15,135 +16,235 @@ class Game:
|
|
|
15
16
|
"""
|
|
16
17
|
self.game_id = Formatter.format_game_id(game_id)
|
|
17
18
|
|
|
18
|
-
def get_boxscore(self) -> List[pd.DataFrame]:
|
|
19
|
+
def get_boxscore(self, standardize: bool = False) -> List[pd.DataFrame]:
|
|
19
20
|
"""Gets traditional boxscore
|
|
20
21
|
|
|
22
|
+
Args:
|
|
23
|
+
standardize: Whether to apply data standardization
|
|
24
|
+
|
|
21
25
|
Returns:
|
|
22
26
|
List[pd.DataFrame]: list of dataframes (players, starters/bench, team)
|
|
23
27
|
"""
|
|
24
|
-
|
|
28
|
+
dfs = nba.BoxScoreTraditionalV3(self.game_id).get_data_frames()
|
|
29
|
+
|
|
30
|
+
if standardize:
|
|
31
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
32
|
+
|
|
33
|
+
self.boxscore = dfs
|
|
25
34
|
return self.boxscore
|
|
26
35
|
|
|
27
|
-
def get_advanced(self):
|
|
36
|
+
def get_advanced(self, standardize: bool = False):
|
|
28
37
|
"""
|
|
29
38
|
Retrieves the advanced box score data for the game.
|
|
30
39
|
|
|
40
|
+
Args:
|
|
41
|
+
standardize: Whether to apply data standardization
|
|
42
|
+
|
|
31
43
|
Returns:
|
|
32
44
|
pandas.DataFrame: The advanced box score data for the game.
|
|
33
45
|
"""
|
|
34
|
-
|
|
46
|
+
dfs = nba.BoxScoreAdvancedV3(self.game_id).get_data_frames()
|
|
47
|
+
|
|
48
|
+
if standardize:
|
|
49
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
50
|
+
|
|
51
|
+
self.adv_box = dfs
|
|
35
52
|
return self.adv_box
|
|
36
53
|
|
|
37
|
-
def get_defense(self):
|
|
54
|
+
def get_defense(self, standardize: bool = False):
|
|
38
55
|
"""
|
|
39
56
|
Retrieves the defensive statistics for the game.
|
|
40
57
|
|
|
58
|
+
Args:
|
|
59
|
+
standardize: Whether to apply data standardization
|
|
60
|
+
|
|
41
61
|
Returns:
|
|
42
62
|
def_box (pandas.DataFrame): DataFrame containing the defensive statistics.
|
|
43
63
|
"""
|
|
44
|
-
|
|
64
|
+
dfs = nba.BoxScoreDefensiveV2(self.game_id).get_data_frames()
|
|
65
|
+
|
|
66
|
+
if standardize:
|
|
67
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
68
|
+
|
|
69
|
+
self.def_box = dfs
|
|
45
70
|
return self.def_box
|
|
46
71
|
|
|
47
|
-
def get_four_factors(self):
|
|
72
|
+
def get_four_factors(self, standardize: bool = False):
|
|
48
73
|
"""
|
|
49
74
|
Retrieves the four factors data for the game.
|
|
50
75
|
|
|
76
|
+
Args:
|
|
77
|
+
standardize: Whether to apply data standardization
|
|
78
|
+
|
|
51
79
|
Returns:
|
|
52
80
|
pandas.DataFrame: The four factors data for the game.
|
|
53
81
|
"""
|
|
54
|
-
|
|
82
|
+
dfs = nba.BoxScoreFourFactorsV3(self.game_id).get_data_frames()
|
|
83
|
+
|
|
84
|
+
if standardize:
|
|
85
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
86
|
+
|
|
87
|
+
self.four_factors = dfs
|
|
55
88
|
return self.four_factors
|
|
56
89
|
|
|
57
|
-
def get_hustle(self) -> List[pd.DataFrame]:
|
|
90
|
+
def get_hustle(self, standardize: bool = False) -> List[pd.DataFrame]:
|
|
58
91
|
"""Gets hustle data for a given game
|
|
59
92
|
|
|
93
|
+
Args:
|
|
94
|
+
standardize: Whether to apply data standardization
|
|
95
|
+
|
|
60
96
|
Returns:
|
|
61
97
|
List[pd.DataFrame]: list of two dataframes (players, teams)
|
|
62
98
|
"""
|
|
63
|
-
|
|
99
|
+
dfs = nba.BoxScoreHustleV2(self.game_id).get_data_frames()
|
|
100
|
+
|
|
101
|
+
if standardize:
|
|
102
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
103
|
+
|
|
104
|
+
self.hustle = dfs
|
|
64
105
|
return self.hustle
|
|
65
106
|
|
|
66
|
-
def get_matchups(self):
|
|
107
|
+
def get_matchups(self, standardize: bool = False):
|
|
67
108
|
"""
|
|
68
109
|
Retrieves the matchups for the game.
|
|
69
110
|
|
|
111
|
+
Args:
|
|
112
|
+
standardize: Whether to apply data standardization
|
|
113
|
+
|
|
70
114
|
Returns:
|
|
71
115
|
pandas.DataFrame: The matchups data for the game.
|
|
72
116
|
"""
|
|
73
|
-
|
|
117
|
+
dfs = nba.BoxScoreMatchupsV3(self.game_id).get_data_frames()
|
|
118
|
+
|
|
119
|
+
if standardize:
|
|
120
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
121
|
+
|
|
122
|
+
self.matchups = dfs
|
|
74
123
|
return self.matchups
|
|
75
124
|
|
|
76
|
-
def get_misc(self):
|
|
125
|
+
def get_misc(self, standardize: bool = False):
|
|
77
126
|
"""
|
|
78
127
|
Retrieves miscellaneous box score data for the game.
|
|
79
128
|
|
|
129
|
+
Args:
|
|
130
|
+
standardize: Whether to apply data standardization
|
|
131
|
+
|
|
80
132
|
Returns:
|
|
81
133
|
pandas.DataFrame: The miscellaneous box score data.
|
|
82
134
|
"""
|
|
83
|
-
|
|
135
|
+
dfs = nba.BoxScoreMiscV3(self.game_id).get_data_frames()
|
|
136
|
+
|
|
137
|
+
if standardize:
|
|
138
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
139
|
+
|
|
140
|
+
self.misc = dfs
|
|
84
141
|
return self.misc
|
|
85
142
|
|
|
86
|
-
def get_scoring(self):
|
|
143
|
+
def get_scoring(self, standardize: bool = False):
|
|
87
144
|
"""
|
|
88
145
|
Retrieves the scoring data for the game.
|
|
89
146
|
|
|
147
|
+
Args:
|
|
148
|
+
standardize: Whether to apply data standardization
|
|
149
|
+
|
|
90
150
|
Returns:
|
|
91
151
|
pandas.DataFrame: The scoring data for the game.
|
|
92
152
|
"""
|
|
93
|
-
|
|
153
|
+
dfs = nba.BoxScoreScoringV3(self.game_id).get_data_frames()
|
|
154
|
+
|
|
155
|
+
if standardize:
|
|
156
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
157
|
+
|
|
158
|
+
self.scoring = dfs
|
|
94
159
|
return self.scoring
|
|
95
160
|
|
|
96
|
-
def get_usage(self) -> List[pd.DataFrame]:
|
|
161
|
+
def get_usage(self, standardize: bool = False) -> List[pd.DataFrame]:
|
|
97
162
|
"""Gets usage data for a given game
|
|
98
163
|
|
|
164
|
+
Args:
|
|
165
|
+
standardize: Whether to apply data standardization
|
|
166
|
+
|
|
99
167
|
Returns:
|
|
100
168
|
List[pd.DataFrame]: list of two dataframes (players, teams)
|
|
101
169
|
"""
|
|
102
|
-
|
|
170
|
+
dfs = nba.BoxScoreUsageV3(self.game_id).get_data_frames()
|
|
171
|
+
|
|
172
|
+
if standardize:
|
|
173
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
174
|
+
|
|
175
|
+
self.usage = dfs
|
|
103
176
|
return self.usage
|
|
104
177
|
|
|
105
|
-
def get_playertrack(self):
|
|
178
|
+
def get_playertrack(self, standardize: bool = False):
|
|
106
179
|
"""
|
|
107
180
|
Retrieves the player tracking data for the game.
|
|
108
181
|
|
|
182
|
+
Args:
|
|
183
|
+
standardize: Whether to apply data standardization
|
|
184
|
+
|
|
109
185
|
Returns:
|
|
110
186
|
playertrack (pandas.DataFrame): The player tracking data for the game.
|
|
111
187
|
"""
|
|
112
|
-
|
|
188
|
+
dfs = nba.BoxScorePlayerTrackV3(self.game_id).get_data_frames()
|
|
189
|
+
|
|
190
|
+
if standardize:
|
|
191
|
+
dfs = [standardize_dataframe(df, data_type="game") for df in dfs]
|
|
192
|
+
|
|
193
|
+
self.playertrack = dfs
|
|
113
194
|
return self.playertrack
|
|
114
195
|
|
|
115
|
-
def get_rotations(self):
|
|
196
|
+
def get_rotations(self, standardize: bool = False):
|
|
116
197
|
"""
|
|
117
198
|
Retrieves the rotations data for the game.
|
|
118
199
|
|
|
200
|
+
Args:
|
|
201
|
+
standardize: Whether to apply data standardization
|
|
202
|
+
|
|
119
203
|
Returns:
|
|
120
204
|
pandas.DataFrame: The rotations data for the game.
|
|
121
205
|
"""
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
206
|
+
df = pd.concat(nba.GameRotation(game_id=self.game_id).get_data_frames())
|
|
207
|
+
|
|
208
|
+
if standardize:
|
|
209
|
+
df = standardize_dataframe(df, data_type="game")
|
|
210
|
+
|
|
211
|
+
self.rotations = df
|
|
125
212
|
return self.rotations
|
|
126
213
|
|
|
127
|
-
def get_playbyplay(self) -> pd.DataFrame:
|
|
214
|
+
def get_playbyplay(self, standardize: bool = False) -> pd.DataFrame:
|
|
128
215
|
"""
|
|
129
216
|
Retrieves the play-by-play data for the game.
|
|
130
217
|
|
|
218
|
+
Args:
|
|
219
|
+
standardize: Whether to apply data standardization
|
|
220
|
+
|
|
131
221
|
Returns:
|
|
132
222
|
pd.DataFrame: The play-by-play data as a pandas DataFrame.
|
|
133
223
|
"""
|
|
134
|
-
|
|
224
|
+
df = nba.PlayByPlayV3(self.game_id).get_data_frames()[0]
|
|
225
|
+
|
|
226
|
+
if standardize:
|
|
227
|
+
df = standardize_dataframe(df, data_type="game")
|
|
228
|
+
|
|
229
|
+
self.playbyplay = df
|
|
135
230
|
return self.playbyplay
|
|
136
231
|
|
|
137
|
-
def get_win_probability(self) -> pd.DataFrame:
|
|
232
|
+
def get_win_probability(self, standardize: bool = False) -> pd.DataFrame:
|
|
138
233
|
"""
|
|
139
234
|
Retrieves the win probability data for the game.
|
|
140
235
|
|
|
236
|
+
Args:
|
|
237
|
+
standardize: Whether to apply data standardization
|
|
238
|
+
|
|
141
239
|
Returns:
|
|
142
240
|
pd.DataFrame: The win probability data as a pandas DataFrame.
|
|
143
241
|
"""
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
242
|
+
df = nba.WinProbabilityPBP(game_id=self.game_id).get_data_frames()[0]
|
|
243
|
+
|
|
244
|
+
if standardize:
|
|
245
|
+
df = standardize_dataframe(df, data_type="game")
|
|
246
|
+
|
|
247
|
+
self.win_probability = df
|
|
147
248
|
return self.win_probability
|
|
148
249
|
|
|
149
250
|
|
nbastatpy/player.py
CHANGED
|
@@ -9,6 +9,7 @@ from nba_api.stats.endpoints import leaguegamefinder
|
|
|
9
9
|
from nba_api.stats.static import players, teams
|
|
10
10
|
from PIL import Image
|
|
11
11
|
|
|
12
|
+
from nbastatpy.standardize import standardize_dataframe
|
|
12
13
|
from nbastatpy.utils import Formatter, PlayTypes
|
|
13
14
|
|
|
14
15
|
|
|
@@ -59,21 +60,26 @@ class Player:
|
|
|
59
60
|
if playoffs:
|
|
60
61
|
self.season_type = "Playoffs"
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
def get_common_info(self) -> pd.DataFrame:
|
|
63
|
+
def get_common_info(self, standardize: bool = False) -> pd.DataFrame:
|
|
64
64
|
"""Gets common info like height, weight, draft_year, etc. and sets as class attr
|
|
65
|
-
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
standardize: Whether to apply data standardization
|
|
68
|
+
|
|
66
69
|
Returns:
|
|
67
70
|
pd.DataFrame: A DataFrame containing the common information of the player.
|
|
68
71
|
"""
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
df = nba.CommonPlayerInfo(self.id).get_data_frames()[0]
|
|
73
|
+
|
|
74
|
+
if standardize:
|
|
75
|
+
df = standardize_dataframe(df, data_type="player")
|
|
76
|
+
|
|
77
|
+
self.common_info = df.iloc[0].to_dict()
|
|
72
78
|
|
|
73
79
|
for attr_name, value in self.common_info.items():
|
|
74
80
|
setattr(self, attr_name.lower(), self.common_info.get(attr_name, None))
|
|
75
81
|
|
|
76
|
-
return
|
|
82
|
+
return df
|
|
77
83
|
|
|
78
84
|
def get_salary(self) -> pd.DataFrame:
|
|
79
85
|
"""
|
|
@@ -88,23 +94,32 @@ class Player:
|
|
|
88
94
|
tables = soup.find_all("table")
|
|
89
95
|
if len(tables) > 1:
|
|
90
96
|
# Get the table rows
|
|
91
|
-
rows = [
|
|
97
|
+
rows = [
|
|
98
|
+
[cell.text.strip() for cell in row.find_all("td")]
|
|
99
|
+
for row in tables[0].find_all("tr")
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
rows2 = [
|
|
103
|
+
[cell.text.strip() for cell in row.find_all("td")]
|
|
104
|
+
for row in tables[1].find_all("tr")
|
|
105
|
+
]
|
|
92
106
|
|
|
93
|
-
rows2 = [[cell.text.strip() for cell in row.find_all('td')] for row in tables[1].find_all('tr')]
|
|
94
|
-
|
|
95
107
|
projected = pd.DataFrame(rows[1:], columns=rows[0])
|
|
96
108
|
projected["Team"] = projected.columns[1]
|
|
97
|
-
projected = projected.rename(columns={projected.columns[1]:"Salary"})
|
|
109
|
+
projected = projected.rename(columns={projected.columns[1]: "Salary"})
|
|
98
110
|
projected["Salary_Type"] = "Projected"
|
|
99
|
-
|
|
111
|
+
|
|
100
112
|
historical = pd.DataFrame(rows2[1:], columns=rows2[0])
|
|
101
113
|
historical["Salary_Type"] = "Historical"
|
|
102
|
-
|
|
114
|
+
|
|
103
115
|
self.salary_df = pd.concat([projected, historical])
|
|
104
|
-
|
|
116
|
+
|
|
105
117
|
else:
|
|
106
118
|
# Get the table rows
|
|
107
|
-
rows = [
|
|
119
|
+
rows = [
|
|
120
|
+
[cell.text.strip() for cell in row.find_all("td")]
|
|
121
|
+
for row in tables[0].find_all("tr")
|
|
122
|
+
]
|
|
108
123
|
self.salary_df = pd.DataFrame(rows[1:], columns=rows[0])
|
|
109
124
|
|
|
110
125
|
return self.salary_df
|
|
@@ -121,15 +136,24 @@ class Player:
|
|
|
121
136
|
self.headshot = Image.open(BytesIO(pic.content))
|
|
122
137
|
return self.headshot
|
|
123
138
|
|
|
124
|
-
def get_season_career_totals(self) -> pd.DataFrame:
|
|
139
|
+
def get_season_career_totals(self, standardize: bool = False) -> pd.DataFrame:
|
|
125
140
|
"""Gets seasons and career data
|
|
126
141
|
|
|
142
|
+
Args:
|
|
143
|
+
standardize: Whether to apply data standardization
|
|
144
|
+
|
|
127
145
|
Returns:
|
|
128
146
|
pd.DataFrame: 2 dataframes, season totals and career
|
|
129
147
|
"""
|
|
130
148
|
df_list = nba.PlayerCareerStats(player_id=self.id).get_data_frames()
|
|
131
|
-
|
|
132
|
-
|
|
149
|
+
|
|
150
|
+
if standardize:
|
|
151
|
+
self.career_totals = standardize_dataframe(df_list[1], data_type="player")
|
|
152
|
+
self.season_totals = standardize_dataframe(df_list[0], data_type="player")
|
|
153
|
+
else:
|
|
154
|
+
self.career_totals = df_list[1]
|
|
155
|
+
self.season_totals = df_list[0]
|
|
156
|
+
|
|
133
157
|
return self.season_totals, self.career_totals
|
|
134
158
|
|
|
135
159
|
def get_splits(self) -> pd.DataFrame:
|
|
@@ -164,7 +188,6 @@ class Player:
|
|
|
164
188
|
return self.game_splits
|
|
165
189
|
|
|
166
190
|
def get_shooting_splits(self) -> pd.DataFrame:
|
|
167
|
-
|
|
168
191
|
self.shooting_splits = pd.concat(
|
|
169
192
|
nba.PlayerDashboardByShootingSplits(
|
|
170
193
|
self.id,
|
|
@@ -209,18 +232,31 @@ class Player:
|
|
|
209
232
|
self.awards = nba.PlayerAwards(self.id).get_data_frames()[0]
|
|
210
233
|
return self.awards
|
|
211
234
|
|
|
212
|
-
def get_games_boxscore(self) -> pd.DataFrame:
|
|
235
|
+
def get_games_boxscore(self, standardize: bool = False) -> pd.DataFrame:
|
|
213
236
|
"""
|
|
214
237
|
Retrieves the boxscore data for the games played by the player.
|
|
215
238
|
|
|
239
|
+
Args:
|
|
240
|
+
standardize: Whether to apply data standardization
|
|
241
|
+
|
|
216
242
|
Returns:
|
|
217
243
|
pd.DataFrame: The boxscore data for the player's games.
|
|
218
244
|
"""
|
|
219
|
-
|
|
245
|
+
df = leaguegamefinder.LeagueGameFinder(
|
|
220
246
|
player_id_nullable=self.id,
|
|
221
247
|
season_nullable=self.season,
|
|
222
248
|
season_type_nullable=self.season_type,
|
|
223
249
|
).get_data_frames()[0]
|
|
250
|
+
|
|
251
|
+
if standardize:
|
|
252
|
+
df = standardize_dataframe(
|
|
253
|
+
df,
|
|
254
|
+
data_type="player",
|
|
255
|
+
season=self.season,
|
|
256
|
+
playoffs=(self.season_type == "Playoffs"),
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
self.games_boxscore = df
|
|
224
260
|
return self.games_boxscore
|
|
225
261
|
|
|
226
262
|
def get_matchups(self, defense: bool = False) -> pd.DataFrame:
|
|
@@ -228,7 +264,7 @@ class Player:
|
|
|
228
264
|
Retrieves the matchups data for the player.
|
|
229
265
|
|
|
230
266
|
Args:
|
|
231
|
-
defense (bool, optional): If True, retrieves the defensive matchups data.
|
|
267
|
+
defense (bool, optional): If True, retrieves the defensive matchups data.
|
|
232
268
|
If False, retrieves the offensive matchups data. Defaults to False.
|
|
233
269
|
|
|
234
270
|
Returns:
|