rustat-python-api 0.5.3__py3-none-any.whl → 0.5.4__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.
- rustat_python_api/parser.py +74 -0
- rustat_python_api/pitch_control.py +9 -7
- rustat_python_api/urls.py +1 -0
- {rustat_python_api-0.5.3.dist-info → rustat_python_api-0.5.4.dist-info}/METADATA +1 -1
- rustat_python_api-0.5.4.dist-info/RECORD +12 -0
- rustat_python_api-0.5.3.dist-info/RECORD +0 -12
- {rustat_python_api-0.5.3.dist-info → rustat_python_api-0.5.4.dist-info}/LICENSE +0 -0
- {rustat_python_api-0.5.3.dist-info → rustat_python_api-0.5.4.dist-info}/WHEEL +0 -0
- {rustat_python_api-0.5.3.dist-info → rustat_python_api-0.5.4.dist-info}/top_level.txt +0 -0
rustat_python_api/parser.py
CHANGED
|
@@ -173,6 +173,80 @@ class RuStatParser:
|
|
|
173
173
|
|
|
174
174
|
return df
|
|
175
175
|
|
|
176
|
+
def get_tracking_30fps(
|
|
177
|
+
self,
|
|
178
|
+
match_id: int, half: int, lang_id: int = 0,
|
|
179
|
+
referee_data: int = 0, ball_data: int = 1
|
|
180
|
+
) -> pd.DataFrame | tuple | None:
|
|
181
|
+
data = self.resp2data(
|
|
182
|
+
self.urls["tracking_30fps"].format(
|
|
183
|
+
user=self.user,
|
|
184
|
+
password=self.password,
|
|
185
|
+
match_id=match_id,
|
|
186
|
+
half=half,
|
|
187
|
+
lang_id=lang_id,
|
|
188
|
+
referee_data=referee_data,
|
|
189
|
+
ball_data=ball_data
|
|
190
|
+
)
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
if not data:
|
|
194
|
+
return None
|
|
195
|
+
|
|
196
|
+
teams_data = data['data']['teams']
|
|
197
|
+
if 'ball' in data['data']:
|
|
198
|
+
ball_data = data['data']['ball']
|
|
199
|
+
if 'referee' in data['data']:
|
|
200
|
+
referee_data = data['data']['referee']
|
|
201
|
+
del data
|
|
202
|
+
|
|
203
|
+
tracking = pd.DataFrame(columns=[
|
|
204
|
+
"half", "second", "pos_x", "pos_y", "team_id", "player_id", "player_name", "distance", "speed"
|
|
205
|
+
])
|
|
206
|
+
|
|
207
|
+
for team_data in tqdm(teams_data):
|
|
208
|
+
team_id = team_data["id"]
|
|
209
|
+
side_1h = team_data["gate_position_half_1"]
|
|
210
|
+
|
|
211
|
+
for player_data in team_data["players"]:
|
|
212
|
+
player_id = player_data["id"]
|
|
213
|
+
player_name = player_data["name"]
|
|
214
|
+
|
|
215
|
+
cur_df = pd.json_normalize(player_data["rows"])
|
|
216
|
+
cur_df = cur_df.apply(pd.to_numeric, errors='coerce')
|
|
217
|
+
cur_df["team_id"] = team_id
|
|
218
|
+
cur_df["player_id"] = player_id
|
|
219
|
+
cur_df["player_name"] = player_name
|
|
220
|
+
cur_df["side_1h"] = side_1h
|
|
221
|
+
|
|
222
|
+
tracking = pd.concat([tracking, cur_df], ignore_index=True)
|
|
223
|
+
|
|
224
|
+
tracking['second'] = tracking['second'].astype(float)
|
|
225
|
+
tracking = tracking.sort_values(by=['half', 'second', 'team_id', 'player_id']).reset_index(drop=True)
|
|
226
|
+
tracking['pos_x'] = tracking['pos_x'] + 105/2
|
|
227
|
+
tracking['team_id'] = tracking['team_id'].astype(str)
|
|
228
|
+
|
|
229
|
+
if referee_data:
|
|
230
|
+
referee = pd.json_normalize(referee_data['rows'])
|
|
231
|
+
referee['second'] = referee['second'].astype(float)
|
|
232
|
+
referee = referee.sort_values(by=['half', 'second']).reset_index(drop=True)
|
|
233
|
+
referee['pos_x'] = referee['pos_x'] + 105/2
|
|
234
|
+
|
|
235
|
+
if ball_data:
|
|
236
|
+
ball = pd.json_normalize(ball_data['rows'])
|
|
237
|
+
ball['second'] = ball['second'].astype(float)
|
|
238
|
+
ball = ball.sort_values(by=['half', 'second']).reset_index(drop=True)
|
|
239
|
+
ball['pos_x'] = ball['pos_x'] + 105/2
|
|
240
|
+
|
|
241
|
+
if referee_data and ball_data:
|
|
242
|
+
return tracking, referee, ball
|
|
243
|
+
elif referee_data:
|
|
244
|
+
return tracking, referee
|
|
245
|
+
elif ball_data:
|
|
246
|
+
return tracking, ball
|
|
247
|
+
else:
|
|
248
|
+
return tracking
|
|
249
|
+
|
|
176
250
|
def get_match_stats(self, match_id: int) -> dict:
|
|
177
251
|
data = self.resp2data(
|
|
178
252
|
self.urls["match_stats"].format(
|
|
@@ -7,7 +7,7 @@ import matplotsoccer as mpl
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class PitchControl:
|
|
10
|
-
def __init__(self, tracking: pd.DataFrame, events: pd.DataFrame):
|
|
10
|
+
def __init__(self, tracking: pd.DataFrame, events: pd.DataFrame, ball_data: pd.DataFrame = None):
|
|
11
11
|
self.team_ids = tracking['team_id'].unique()
|
|
12
12
|
sides = tracking.groupby('team_id')['side_1h'].unique()
|
|
13
13
|
side_by_team = dict(zip(self.team_ids, sides[self.team_ids].apply(lambda x: x[0])))
|
|
@@ -22,10 +22,11 @@ class PitchControl:
|
|
|
22
22
|
|
|
23
23
|
self.locs_home, self.locs_away, self.locs_ball, self.t = self.get_locs(
|
|
24
24
|
tracking,
|
|
25
|
-
events
|
|
25
|
+
events,
|
|
26
|
+
ball_data
|
|
26
27
|
)
|
|
27
28
|
|
|
28
|
-
def get_locs(self, tracking: pd.DataFrame, events: pd.DataFrame) -> tuple:
|
|
29
|
+
def get_locs(self, tracking: pd.DataFrame, events: pd.DataFrame, ball_data: pd.DataFrame | None) -> tuple:
|
|
29
30
|
events = events[[
|
|
30
31
|
'possession_number', 'team_id', 'possession_team_id',
|
|
31
32
|
'half', 'second', 'pos_x', 'pos_y'
|
|
@@ -38,10 +39,11 @@ class PitchControl:
|
|
|
38
39
|
lambda x: self.swap_coords(x, 'y'), axis=1
|
|
39
40
|
)
|
|
40
41
|
|
|
41
|
-
ball_data
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
if ball_data is None:
|
|
43
|
+
ball_data = self.interpolate_ball_data(
|
|
44
|
+
events[['half', 'second', 'pos_x', 'pos_y']],
|
|
45
|
+
tracking
|
|
46
|
+
)
|
|
45
47
|
|
|
46
48
|
locs_home = {
|
|
47
49
|
half: {
|
rustat_python_api/urls.py
CHANGED
|
@@ -4,5 +4,6 @@ URLs = {
|
|
|
4
4
|
"match_stats": "http://feeds.rustatsport.ru/?tpl=207&user={user}&key={password}&match_id={match_id}&lang_id=1&format=json",
|
|
5
5
|
"tournament_teams": "http://feeds.rustatsport.ru/?tpl=32&user={user}&key={password}&tournament_id=2&season_id={season_id}&date_start=&date_end=&lang_id=1&format=json",
|
|
6
6
|
"tracking": "https://feeds.rustatsport.ru/?tpl=274&user={user}&key={password}&match_id={match_id}&lang_id=0&format=json",
|
|
7
|
+
"tracking_30fps": "https://feeds.rustatsport.ru/?tpl=1013&user={user}&key={password}&match_id={match_id}&referee_data={referee_data}&ball_data={ball_data}&half={half}&lang_id={lang_id}&format=json",
|
|
7
8
|
"player_match_stats": "http://feeds.rustatsport.ru/?tpl=227&user={user}&key={password}&match_id={match_id}&lang_id=1&format=json"
|
|
8
9
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
rustat_python_api/__init__.py,sha256=Ij-PAm2y5ss_XAZhKTZus35cRPLzvXFyIswDa_Iq3rs,164
|
|
2
|
+
rustat_python_api/config.py,sha256=eMvi1p8Cfvnbp6Cd4bBOwgehVN7thKnaQV5uzWyGZXM,1844
|
|
3
|
+
rustat_python_api/models_api.py,sha256=oHXEqeCupvZwjVEdoxf7W9LP7ELFKA8-9DuRXpQHLno,1701
|
|
4
|
+
rustat_python_api/parser.py,sha256=YsA4apnm0xolfUC8E2YUSfhDkUugCR2dUhG9iZKsn2E,9861
|
|
5
|
+
rustat_python_api/pitch_control.py,sha256=wBL9X310OBeFvheJssLR4e7wX5suUPjHegZKbEun1Lo,11540
|
|
6
|
+
rustat_python_api/processing.py,sha256=46O7wUGv5boWf4A38zYinbtqEC7ke-BwTdEg589XQaw,2816
|
|
7
|
+
rustat_python_api/urls.py,sha256=iJTD31T6OyXPAhmhViwFXVehrzwsOjBDONA1SIVc_40,1068
|
|
8
|
+
rustat_python_api-0.5.4.dist-info/LICENSE,sha256=4Cohqg5p6Mq1xyrzdEX8AvFSA62GSVvapEOr2xK_tgY,57
|
|
9
|
+
rustat_python_api-0.5.4.dist-info/METADATA,sha256=KU_FqqVPi4RiD5BPq-MvDpRqTs6y0MPYiMWajcxGL08,1730
|
|
10
|
+
rustat_python_api-0.5.4.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
|
11
|
+
rustat_python_api-0.5.4.dist-info/top_level.txt,sha256=VK0hmkKZE9YThxolUcoE6JtGI67NFeKJMBLuet8kI4w,18
|
|
12
|
+
rustat_python_api-0.5.4.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
rustat_python_api/__init__.py,sha256=Ij-PAm2y5ss_XAZhKTZus35cRPLzvXFyIswDa_Iq3rs,164
|
|
2
|
-
rustat_python_api/config.py,sha256=eMvi1p8Cfvnbp6Cd4bBOwgehVN7thKnaQV5uzWyGZXM,1844
|
|
3
|
-
rustat_python_api/models_api.py,sha256=oHXEqeCupvZwjVEdoxf7W9LP7ELFKA8-9DuRXpQHLno,1701
|
|
4
|
-
rustat_python_api/parser.py,sha256=ATZzBctIiTs7rcPeszmiMExbQ_Nkra-7xWtw8JBTNI4,7103
|
|
5
|
-
rustat_python_api/pitch_control.py,sha256=2tIiLtGBgANRet9csfZPZo2b2enxRDLREf5g1a6YpcM,11407
|
|
6
|
-
rustat_python_api/processing.py,sha256=46O7wUGv5boWf4A38zYinbtqEC7ke-BwTdEg589XQaw,2816
|
|
7
|
-
rustat_python_api/urls.py,sha256=MIUDXq5QFacyVWbrIIuMbwf-WRARsxb32kFY97zw4OQ,865
|
|
8
|
-
rustat_python_api-0.5.3.dist-info/LICENSE,sha256=4Cohqg5p6Mq1xyrzdEX8AvFSA62GSVvapEOr2xK_tgY,57
|
|
9
|
-
rustat_python_api-0.5.3.dist-info/METADATA,sha256=4697XDS-Yqmv79JQ6iRQC5wirzkkDZ29lkfmaIVEBO8,1730
|
|
10
|
-
rustat_python_api-0.5.3.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
|
11
|
-
rustat_python_api-0.5.3.dist-info/top_level.txt,sha256=VK0hmkKZE9YThxolUcoE6JtGI67NFeKJMBLuet8kI4w,18
|
|
12
|
-
rustat_python_api-0.5.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|