UFCData 0.2.0__tar.gz → 0.3.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: UFCData
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Obtain UFC data and functions to manipulate it
5
5
  Requires-Python: >=3.10
6
6
  License-File: LICENSE.md
@@ -14,23 +14,22 @@ Accessing Data
14
14
  - [Loading Data](#loading-data)
15
15
  - [Search](#search)
16
16
 
17
- Rating Functions
17
+ Rating Function
18
18
  - [Elo](#elo)
19
- - [Glicko-2](#glicko-2)
20
19
 
21
20
  Fighter Functions
22
- - [Fighter Record](#elo)
21
+ - [Fighter History](#elo)
23
22
  - [Fighter Statistic](#elo)
24
23
 
25
- Model Evaluation
26
- - [Odds Baseline Example](#elo)
27
-
28
24
  Helper Functions
29
25
  - [Odds Convert](#elo)
30
26
  - [Weight Convert](#elo)
31
27
  - [Gender Convert](#elo)
32
28
  - [Mirror](#elo)
33
29
 
30
+ Model Evaluation
31
+ - [Odds Baseline Example](#elo)
32
+
34
33
  Data Sources
35
34
  - [Online Sources](#online-sources)
36
35
  - [Discrepancies in Data](#discrepancies-in-data)
@@ -80,7 +79,8 @@ This searches the `"Name"` column of the `fighter_bio` dataframe for the three c
80
79
 
81
80
  The results are returned as a dataframe, with the closest match appearing first.
82
81
 
83
- Output:
82
+ ### Returns
83
+
84
84
 
85
85
  ```text
86
86
  Name Nickname Height Weight Reach Stance Total W Total L Fighter Link
@@ -116,7 +116,8 @@ ufc.get_elo(fight_df, fighter_df, r=1500, k=30, s=400)
116
116
  The function returns a tuple containing:
117
117
 
118
118
  1. `fighter_elo` — A dictionary mapping each fighter's UFCStats link to their final Elo rating.
119
- 2. `elo` — A dataframe containing fight-level Elo ratings. `"Fighter 1 Elo"` and `"Fighter 2 Elo"` represent each fighter's rating immediately before the corresponding fight.
119
+ 2. `elo` — The original `fights_df` dataframe with `"Fighter 1 Elo"` and `"Fighter 2 Elo"` columns added. These columns contain each fighter's Elo rating immediately prior to the corresponding fight.
120
+
120
121
 
121
122
  ### Example
122
123
 
@@ -125,12 +126,12 @@ import ufcdata as ufc
125
126
 
126
127
  data = ufc.get_data()
127
128
 
128
- fight_df = data["past_fights"].copy()
129
- fighter_df = data["fighter_bio"].copy()
129
+ past_fights = data["past_fights"].copy()
130
+ fighter_bio = data["fighter_bio"].copy()
130
131
 
131
- fighter_elo, fight_elo = ufc.get_elo(
132
- fight_df,
133
- fighter_df
132
+ current_elo, past_elo = ufc.get_elo(
133
+ past_fights,
134
+ fighter_bio
134
135
  )
135
136
  ```
136
137
 
@@ -141,14 +142,56 @@ The resulting `fight_elo` dataframe can then be used to examine or incorporate p
141
142
 
142
143
  `fight_df` should be sorted from **most recent to least recent** before being passed to `get_elo()`. The function reverses the dataframe internally to process fights chronologically and returns the resulting data in the original order.
143
144
 
145
+ ## Fighter History
146
+
147
+ The `get_fighter_history()` function retrieves all UFC fights for a specific fighter and formats the results from the fighter's perspective. The requested fighter is always represented as `"Fighter 1"`, regardless of which side of the original fight dataframe they appeared on.
148
+
149
+ The function also calculates the age of both fighters at the time of each fight and assigns a `"UFC Fight"` number to each fight.
150
+
151
+
152
+ ```python
153
+ ufc.get_fighter_history(fighter_link, fighter_bio, fights_df)
154
+ ```
155
+
156
+ ### Parameters
157
+
158
+ * `fighter_link` — The UFCStats link identifying the fighter.
159
+ * `fighter_bio` — The fighter information dataframe returned by `get_data()`.
160
+ * `fights_df` — The fight dataframe containing UFC fight history.
161
+
162
+ ### Returns
163
+
164
+ A dataframe containing the fighter's fight history from most recent to least recent. The requested fighter is always `"Fighter 1"`, with fighter ages and `"UFC Fight"` numbers included.
144
165
 
145
- ## Glicko-2
146
- Glicko-2 extends the Elo system by incorporating rating deviation (RD) and volatility. Unlike Elo, which represents a fighter's ability with a single rating, Glicko-2 also estimates the uncertainty and consistency of that rating.
147
166
 
148
- fighter_glicko, fight_glicko = ufc.glicko_2(
149
- fight_df,
150
- fighter_df
167
+
168
+ ### Example
169
+
170
+ ```python
171
+ import ufcdata as ufc
172
+
173
+ data = ufc.get_data()
174
+
175
+ fighter_bio = data["fighter_bio"].copy()
176
+ fights_df = data["past_fights"].copy()
177
+
178
+ # Obtain Jon Jones' UFCStats link
179
+ jon_jones = ufc.search(
180
+ fighter_bio,
181
+ "Name",
182
+ "Jon Jones"
183
+ ).iloc[0]["Fighter Link"]
184
+
185
+ # Get Jon Jones' fight history
186
+ jon_jones_history = ufc.get_fighter_history(
187
+ jon_jones,
188
+ fighter_bio,
189
+ fights_df
151
190
  )
191
+ ```
192
+
193
+ This function is useful for analyzing an individual fighter's career, constructing fighter-level features, or preparing historical data for predictive modeling.
194
+
152
195
 
153
196
  ## Online Sources
154
197
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: UFCData
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Obtain UFC data and functions to manipulate it
5
5
  Requires-Python: >=3.10
6
6
  License-File: LICENSE.md
@@ -8,6 +8,7 @@ UFCData.egg-info/requires.txt
8
8
  UFCData.egg-info/top_level.txt
9
9
  ufcdata/__init__.py
10
10
  ufcdata/data.py
11
+ ufcdata/fighter.py
11
12
  ufcdata/ratings.py
12
13
  ufcdata/search.py
13
14
  ufcdata.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "UFCData"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "Obtain UFC data and functions to manipulate it"
5
5
  requires-python = ">=3.10"
6
6
 
@@ -0,0 +1,4 @@
1
+ from .data import get_data
2
+ from .search import search
3
+ from .ratings import get_elo
4
+ from .fighter import get_fighter_history
@@ -0,0 +1,701 @@
1
+ import pandas as pd
2
+ import numpy as np
3
+ from datetime import date
4
+ from .ratings import get_elo, expected_score, update_rating
5
+
6
+ def _mirror_helper(df, cols_1, cols_2, in_order=True):
7
+ df = df.copy()
8
+ df_original = df.copy()
9
+
10
+ # Swap each pair of columns
11
+ for c1, c2 in zip(cols_1, cols_2):
12
+ temp = df[c1].copy()
13
+ df[c1] = df[c2]
14
+ df[c2] = temp
15
+
16
+ if not in_order:
17
+ return pd.concat([df_original, df], ignore_index=True)
18
+
19
+ rows = []
20
+ for r1, r2 in zip(df_original.itertuples(index=False), df.itertuples(index=False)):
21
+ rows.append(r1)
22
+ rows.append(r2)
23
+
24
+ return pd.DataFrame(rows, columns=df.columns)
25
+
26
+
27
+ def get_fighter_history(fighter_link, fighter_bio, fights_df):
28
+ """
29
+ Retrieves the fight history of a UFC fighter.
30
+
31
+ The returned DataFrame contains all fights involving the specified
32
+ fighter, with the fighter consistently represented as "Fighter 1".
33
+ The function also calculates the age of both fighters at the time
34
+ of each fight and assigns a chronological UFC fight number.
35
+
36
+ Parameters
37
+ ----------
38
+ fighter_link : str
39
+ UFCStats link identifying the fighter whose history is being
40
+ retrieved.
41
+ fighter_bio : pandas.DataFrame
42
+ DataFrame containing fighter information. Must contain
43
+ "Fighter Link" and "DOB" columns.
44
+ fights_df : pandas.DataFrame
45
+ DataFrame containing UFC fight data. Must contain fighter links,
46
+ fight dates, outcomes, and the other fight information required
47
+ by the function.
48
+
49
+ Returns
50
+ -------
51
+ pandas.DataFrame
52
+ DataFrame containing the fighter's complete fight history.
53
+ The requested fighter is represented as "Fighter 1" in every
54
+ row. The DataFrame includes the ages of both fighters at the
55
+ time of each fight and a "UFC Fight" column numbering the
56
+ fighter's fights chronologically.
57
+
58
+ Notes
59
+ -----
60
+ Fighter ages are calculated using 365.25 days per year. The
61
+ "UFC Fight" column counts fights from the most recent fight
62
+ backwards, with the most recent fight numbered 1.
63
+
64
+ Examples
65
+ --------
66
+ >>> fighter_history = get_fighter_history(
67
+ ... fighter_link,
68
+ ... fighter_bio,
69
+ ... fights_df
70
+ ... )
71
+ >>> fighter_history[["Date", "UFC Fight", "Fighter 1",
72
+ ... "Fighter 1 Age"]].head()
73
+
74
+ """
75
+
76
+ fighter_history = fights_df[
77
+ (fights_df["Fighter 1 Link"] == fighter_link) |
78
+ (fights_df["Fighter 2 Link"] == fighter_link)]
79
+
80
+ fighter_history = _mirror_helper(fighter_history, ['Fighter 1', 'Fighter 1 Odds', 'Fighter 1 Link',
81
+ 'Fighter 1 Outcome', 'Fighter 1 Bonus'],['Fighter 2', 'Fighter 2 Odds',
82
+ 'Fighter 2 Link', 'Fighter 2 Outcome', 'Fighter 2 Bonus'])
83
+
84
+ fighter_history = fighter_history[
85
+ (fighter_history["Fighter 1 Link"] == fighter_link)]
86
+
87
+ fighter_history = fighter_history.merge(
88
+ fighter_bio[["Fighter Link", "DOB"]],
89
+ left_on="Fighter 1 Link",
90
+ right_on="Fighter Link",
91
+ how="left")
92
+ fighter_history = fighter_history.rename(columns={"DOB": "Fighter 1 Age"})
93
+ fighter_history = fighter_history.drop(columns=["Fighter Link"])
94
+ fighter_history["Fighter 1 Age"] = (pd.to_datetime(fighter_history["Date"]) - pd.to_datetime(fighter_history["Fighter 1 Age"])).dt.days / 365.25
95
+
96
+ fighter_history = fighter_history.merge(
97
+ fighter_bio[["Fighter Link", "DOB"]],
98
+ left_on="Fighter 2 Link",
99
+ right_on="Fighter Link",
100
+ how="left")
101
+ fighter_history = fighter_history.rename(columns={"DOB": "Fighter 2 Age"})
102
+ fighter_history = fighter_history.drop(columns=["Fighter Link"])
103
+ fighter_history["Fighter 2 Age"] = (pd.to_datetime(fighter_history["Date"]) - pd.to_datetime(fighter_history["Fighter 2 Age"])).dt.days / 365.25
104
+ fighter_history["UFC Fight"] = range(len(fighter_history), 0, -1)
105
+ fighter_history = fighter_history[['Date', "UFC Fight", 'Event Link', 'Fight Link', 'Weight Class',
106
+ 'Gender', 'Title', 'Fighter 1', 'Fighter 1 Odds', 'Fighter 1 Age', 'Fighter 1 Link',
107
+ 'Fighter 1 Outcome', 'Fighter 1 Bonus', 'Fighter 2', 'Fighter 2 Odds','Fighter 2 Age',
108
+ 'Fighter 2 Link', 'Fighter 2 Outcome', 'Fighter 2 Bonus', 'Method',
109
+ 'Round', 'Time', 'Time Format', 'Referee', 'Details']]
110
+
111
+ return fighter_history
112
+
113
+
114
+
115
+ def get_fighter_statistic(fighter_link, fighter_bio, fights_df, rounds_df, future_df,
116
+ r=1500, k=30, s=400):
117
+
118
+ """
119
+ Generate historical and current statistics for a UFC fighter.
120
+
121
+ The function retrieves the fighter's UFC fight history and constructs
122
+ fight-level statistics from the fighter's perspective. It calculates
123
+ the fighter's UFC record, win rate, Elo rating, cumulative fight time,
124
+ striking statistics, takedown statistics, and submission averages using
125
+ only information available before each fight.
126
+
127
+ For fighters with no previous UFC fights, a baseline row is returned
128
+ with an initial Elo rating and zero UFC wins, losses, draws, and
129
+ no-contests. Historical performance statistics are left as NaN because
130
+ no prior fight data is available.
131
+
132
+ Parameters
133
+ ----------
134
+ fighter_link : str
135
+ URL or unique identifier for the fighter.
136
+ fighter_bio : pandas.DataFrame
137
+ DataFrame containing fighter biographical information, including
138
+ fighter names and links.
139
+ fights_df : pandas.DataFrame
140
+ DataFrame containing UFC fight-level results.
141
+ rounds_df : pandas.DataFrame
142
+ DataFrame containing round-level UFC statistics.
143
+ future_df : pandas.DataFrame
144
+ DataFrame containing the fighter's upcoming fight. The first row
145
+ is used to determine the date for which current statistics are
146
+ calculated.
147
+ r : float, default=1500
148
+ Initial Elo rating assigned to fighters with no previous Elo history.
149
+ k : float, default=30
150
+ Elo update factor.
151
+ s : float, default=400
152
+ Elo scaling factor used when calculating expected scores.
153
+
154
+ Returns
155
+ -------
156
+ current_statistic : pandas.DataFrame
157
+ One-row DataFrame containing the fighter's statistics immediately
158
+ before the upcoming fight. Historical statistics are calculated
159
+ using only fights occurring before the upcoming fight date.
160
+
161
+ past_statistic : pandas.DataFrame
162
+ DataFrame containing the fighter's historical statistics for each
163
+ previous UFC fight, with statistics calculated using only fights
164
+ occurring before each respective fight.
165
+
166
+ Notes
167
+ -----
168
+ The function calculates cumulative statistics rather than statistics
169
+ from a single fight. This prevents information from a future fight from
170
+ being used when generating features for an earlier fight.
171
+
172
+ Historical statistics include:
173
+ - UFC record and win rate
174
+ - Elo rating
175
+ - Total fight time
176
+ - Significant strikes landed per minute (SLpM)
177
+ - Significant strike accuracy and defense
178
+ - Significant strikes absorbed per minute (SApM)
179
+ - Takedown average, accuracy, and defense
180
+ - Submission attempts per 15 minutes
181
+
182
+ Fighters with no previous UFC fights receive an initial Elo rating of
183
+ `r`, while statistics requiring historical fight data are set to NaN.
184
+ """
185
+
186
+ record = get_fighter_history(fighter_link, fighter_bio, fights_df)
187
+
188
+ date = future_df.iloc[0]["Date"]
189
+ date = pd.to_datetime(date).date()
190
+
191
+ if len(record) == 0:
192
+ columns = [
193
+ 'Date', 'UFC Fight', 'Weight Class', 'Gender', 'Title', 'Fighter',
194
+ 'Fighter Link', 'Fighter Outcome', 'UFC W', 'UFC L', 'UFC D', 'UFC NC',
195
+ 'UFC Win Rate', 'Fighter Elo',
196
+ 'Fight Time', 'SLpM', 'Str Acc', 'SApM',
197
+ 'Str Def', 'TD Avg', 'TD Acc', 'TD Def', 'Sub Avg'
198
+ ]
199
+
200
+ fighter_name = fighter_bio.loc[
201
+ fighter_bio["Fighter Link"] == fighter_link,
202
+ "Name"
203
+ ].iloc[0]
204
+
205
+ df = pd.DataFrame([{
206
+ "Date": date,
207
+ "UFC Fight": 1,
208
+ "Weight Class": None,
209
+ "Gender": None,
210
+ "Title": None,
211
+ "Fighter": fighter_name,
212
+ "Fighter Link": fighter_link,
213
+ "Fighter Outcome": None,
214
+ "UFC W": 0,
215
+ "UFC L": 0,
216
+ "UFC D": 0,
217
+ "UFC NC": 0,
218
+ "UFC Win Rate": None,
219
+ "Fighter Elo": r,
220
+ "Fight Time": None,
221
+ "SLpM": None,
222
+ "Str Acc": None,
223
+ "SApM": None,
224
+ "Str Def": None,
225
+ "TD Avg": None,
226
+ "TD Acc": None,
227
+ "TD Def": None,
228
+ "Sub Avg": None
229
+ }], columns=columns)
230
+
231
+ df = df.astype(object).where(pd.notna(df), np.nan)
232
+
233
+ df["UFC Fight"] = df["UFC Fight"].astype("Int64")
234
+ df[["UFC W", "UFC L", "UFC D", "UFC NC"]] = (
235
+ df[["UFC W", "UFC L", "UFC D", "UFC NC"]].astype("Int64")
236
+ )
237
+
238
+ return (df, df)
239
+
240
+ statistic = record[
241
+ ['Date', 'UFC Fight', 'Weight Class',
242
+ 'Gender', 'Title', 'Fighter 1',
243
+ 'Fighter 1 Link', 'Fighter 1 Outcome']
244
+ ].copy()
245
+
246
+ cols = [
247
+ "Date", "UFC Fight", "Weight Class", "Gender",
248
+ "Title", "Fighter 1", "Fighter 1 Link",
249
+ "Fighter 1 Outcome"
250
+ ]
251
+
252
+ statistic[cols] = statistic[cols].iloc[::-1].to_numpy()
253
+
254
+ last = statistic.iloc[-1]
255
+ new_row = last.copy()
256
+ new_row[:] = pd.NA
257
+
258
+ new_row["Date"] = date
259
+ new_row["UFC Fight"] = last["UFC Fight"] + 1
260
+ new_row["Gender"] = last["Gender"]
261
+ new_row["Fighter 1"] = last["Fighter 1"]
262
+ new_row["Fighter 1 Link"] = last["Fighter 1 Link"]
263
+
264
+ statistic = pd.concat(
265
+ [statistic, new_row.to_frame().T],
266
+ ignore_index=True
267
+ )
268
+
269
+ statistic["Date"] = pd.to_datetime(statistic["Date"]).dt.date
270
+
271
+ statistic["UFC W"] = 0
272
+ statistic["UFC L"] = 0
273
+ statistic["UFC D"] = 0
274
+ statistic["UFC NC"] = 0
275
+
276
+ for i in range(1, len(statistic)):
277
+
278
+ # Carry forward previous totals
279
+ statistic.loc[i, "UFC W"] = statistic.loc[i-1, "UFC W"]
280
+ statistic.loc[i, "UFC L"] = statistic.loc[i-1, "UFC L"]
281
+ statistic.loc[i, "UFC D"] = statistic.loc[i-1, "UFC D"]
282
+ statistic.loc[i, "UFC NC"] = statistic.loc[i-1, "UFC NC"]
283
+
284
+ # Update based on previous fight result
285
+ result = statistic.loc[i-1, "Fighter 1 Outcome"]
286
+
287
+ if result == "W":
288
+ statistic.loc[i, "UFC W"] += 1
289
+ elif result == "L":
290
+ statistic.loc[i, "UFC L"] += 1
291
+ elif result == "D":
292
+ statistic.loc[i, "UFC D"] += 1
293
+ elif result == "NC":
294
+ statistic.loc[i, "UFC NC"] += 1
295
+
296
+ statistic = statistic[::-1]
297
+
298
+ statistic[
299
+ ["UFC W", "UFC L", "UFC D", "UFC NC"]
300
+ ] = (
301
+ statistic[
302
+ ["UFC W", "UFC L", "UFC D", "UFC NC"]
303
+ ].iloc[::-1].reset_index(drop=True)
304
+ )
305
+
306
+ statistic["UFC Win Rate"] = (
307
+ statistic["UFC W"] /
308
+ (
309
+ statistic["UFC L"]
310
+ + statistic["UFC D"]
311
+ + statistic["UFC NC"]
312
+ + statistic["UFC W"]
313
+ )
314
+ )
315
+
316
+ # Elo
317
+ current_elo,elo = get_elo(fights_df, fighter_bio, r, k, s)
318
+
319
+ elo = elo[
320
+ (elo["Fighter 1 Link"] == fighter_link) |
321
+ (elo["Fighter 2 Link"] == fighter_link)
322
+ ]
323
+
324
+ elo = elo[
325
+ [
326
+ "Fighter 1", "Fighter 1 Elo", "Fighter 1 Outcome",
327
+ "Fighter 1 Link",
328
+ "Fighter 2", "Fighter 2 Elo", "Fighter 2 Outcome",
329
+ "Fighter 2 Link"
330
+ ]
331
+ ]
332
+
333
+ elo = _mirror_helper(
334
+ elo,
335
+ [
336
+ "Fighter 1", "Fighter 1 Elo",
337
+ "Fighter 1 Outcome", "Fighter 1 Link"
338
+ ],
339
+ [
340
+ "Fighter 2", "Fighter 2 Elo",
341
+ "Fighter 2 Outcome", "Fighter 2 Link"
342
+ ]
343
+ )
344
+
345
+ elo = elo[
346
+ elo["Fighter 1 Link"] == fighter_link
347
+ ]
348
+
349
+ elo = elo.reset_index(drop=True)
350
+
351
+ new_row = pd.DataFrame(
352
+ [[np.nan] * len(elo.columns)],
353
+ columns=elo.columns
354
+ )
355
+
356
+ elo = pd.concat(
357
+ [new_row, elo],
358
+ ignore_index=True
359
+ )
360
+
361
+ fighter_elo = elo.at[1, "Fighter 1 Elo"]
362
+ opponent_elo = elo.at[1, "Fighter 2 Elo"]
363
+ fighter_outcome = elo.at[1, "Fighter 1 Outcome"]
364
+
365
+ if fighter_outcome == "W":
366
+ expected_1 = expected_score(
367
+ fighter_elo,
368
+ opponent_elo,
369
+ s
370
+ )
371
+
372
+ elo_1_new = update_rating(
373
+ fighter_elo,
374
+ k,
375
+ 1,
376
+ expected_1
377
+ )
378
+
379
+ elo.at[0, "Fighter 1 Elo"] = elo_1_new
380
+
381
+ elif fighter_outcome == "L":
382
+ expected_1 = expected_score(
383
+ fighter_elo,
384
+ opponent_elo,
385
+ s
386
+ )
387
+
388
+ elo_1_new = update_rating(
389
+ fighter_elo,
390
+ k,
391
+ 0,
392
+ expected_1
393
+ )
394
+
395
+ elo.at[0, "Fighter 1 Elo"] = elo_1_new
396
+
397
+ elif fighter_outcome == "D":
398
+ expected_1 = expected_score(
399
+ fighter_elo,
400
+ opponent_elo,
401
+ s
402
+ )
403
+
404
+ elo_1_new = update_rating(
405
+ fighter_elo,
406
+ k,
407
+ 0.5,
408
+ expected_1
409
+ )
410
+
411
+ elo.at[0, "Fighter 1 Elo"] = elo_1_new
412
+
413
+ elif fighter_outcome == "NC":
414
+ elo.at[0, "Fighter 1 Elo"] = fighter_elo
415
+
416
+ elo = elo["Fighter 1 Elo"]
417
+ elo = elo.iloc[::-1].reset_index(drop=True)
418
+
419
+ statistic = pd.concat(
420
+ [statistic, elo],
421
+ axis=1
422
+ )
423
+
424
+ # Get fight statistics
425
+ fight_time = get_fighter_history(
426
+ fighter_link,
427
+ fighter_bio,
428
+ fights_df
429
+ )
430
+
431
+ fight_time["new_time"] = fight_time["Time"].apply(
432
+ lambda x: int(x.split(":")[0]) * 60
433
+ + int(x.split(":")[1])
434
+ )
435
+
436
+ fight_time["new_round"] = (
437
+ (fight_time["Round"] - 1) * 60 * 5
438
+ )
439
+
440
+ fight_time["Fight Time"] = (
441
+ fight_time["new_time"]
442
+ + fight_time["new_round"]
443
+ ) / 60
444
+
445
+ statistic["Fight Time"] = statistic["Date"].apply(
446
+ lambda d: fight_time.loc[
447
+ fight_time["Date"].dt.date < d,
448
+ "Fight Time"
449
+ ].sum()
450
+ )
451
+
452
+ rounds = rounds_df
453
+
454
+ rounds = rounds[
455
+ (rounds["Fighter 1 Link"] == fighter_link) |
456
+ (rounds["Fighter 2 Link"] == fighter_link)
457
+ ]
458
+
459
+ rounds = _mirror_helper(
460
+ rounds,
461
+ [
462
+ "Fighter 1", "Fighter 1 Link",
463
+ "Fighter 1 TD", "Fighter 1 Sub Att",
464
+ "Fighter 1 Rev", "Fighter 1 Ctrl",
465
+ "Fighter 1 KD", "Fighter 1 Total SS"
466
+ ],
467
+ [
468
+ "Fighter 2", "Fighter 2 Link",
469
+ "Fighter 2 TD", "Fighter 2 Sub Att",
470
+ "Fighter 2 Rev", "Fighter 2 Ctrl",
471
+ "Fighter 2 KD", "Fighter 2 Total SS"
472
+ ]
473
+ )
474
+
475
+ rounds = rounds[
476
+ rounds["Fighter 1 Link"] == fighter_link
477
+ ]
478
+
479
+ rounds["Sig landed"] = (
480
+ rounds["Fighter 1 Total SS"]
481
+ .str.split()
482
+ .str[0]
483
+ .astype(int)
484
+ )
485
+
486
+ rounds["Sig att"] = (
487
+ rounds["Fighter 1 Total SS"]
488
+ .str.split()
489
+ .str[2]
490
+ .astype(int)
491
+ )
492
+
493
+ rounds["Strike acc"] = (
494
+ rounds["Sig landed"] / rounds["Sig att"]
495
+ )
496
+
497
+ rounds["Strikes absorbed"] = (
498
+ rounds["Fighter 2 Total SS"]
499
+ .str.split()
500
+ .str[0]
501
+ .astype(int)
502
+ )
503
+
504
+ rounds["Opp sig att"] = (
505
+ rounds["Fighter 2 Total SS"]
506
+ .str.split()
507
+ .str[2]
508
+ .astype(int)
509
+ )
510
+
511
+ statistic["SLpM"] = statistic["Date"].apply(
512
+ lambda d: rounds.loc[
513
+ rounds["Date"].dt.date < d,
514
+ "Sig landed"
515
+ ].sum()
516
+ )
517
+
518
+ statistic["SLpM"] = (
519
+ statistic["SLpM"] / statistic["Fight Time"]
520
+ )
521
+
522
+ statistic["Sig landed"] = statistic["Date"].apply(
523
+ lambda d: rounds.loc[
524
+ rounds["Date"].dt.date < d,
525
+ "Sig landed"
526
+ ].sum()
527
+ )
528
+
529
+ statistic["Sig att"] = statistic["Date"].apply(
530
+ lambda d: rounds.loc[
531
+ rounds["Date"].dt.date < d,
532
+ "Sig att"
533
+ ].sum()
534
+ )
535
+
536
+ statistic["Str Acc"] = (
537
+ statistic["Sig landed"] /
538
+ statistic["Sig att"]
539
+ )
540
+
541
+ statistic["SApM"] = statistic["Date"].apply(
542
+ lambda d: rounds.loc[
543
+ rounds["Date"].dt.date < d,
544
+ "Strikes absorbed"
545
+ ].sum()
546
+ )
547
+
548
+ statistic["SApM"] = (
549
+ statistic["SApM"] / statistic["Fight Time"]
550
+ )
551
+
552
+ statistic["Strikes absorbed"] = statistic["Date"].apply(
553
+ lambda d: rounds.loc[
554
+ rounds["Date"].dt.date < d,
555
+ "Strikes absorbed"
556
+ ].sum()
557
+ )
558
+
559
+ statistic["Opp sig att"] = statistic["Date"].apply(
560
+ lambda d: rounds.loc[
561
+ rounds["Date"].dt.date < d,
562
+ "Opp sig att"
563
+ ].sum()
564
+ )
565
+
566
+ statistic["Str Def"] = 1 - (
567
+ statistic["Strikes absorbed"] /
568
+ statistic["Opp sig att"]
569
+ )
570
+
571
+ rounds["Td"] = (
572
+ rounds["Fighter 1 TD"]
573
+ .str.split()
574
+ .str[0]
575
+ .astype(int)
576
+ )
577
+
578
+ rounds["TD landed"] = (
579
+ rounds["Fighter 1 TD"]
580
+ .str.split()
581
+ .str[0]
582
+ .astype(int)
583
+ )
584
+
585
+ rounds["TD att"] = (
586
+ rounds["Fighter 1 TD"]
587
+ .str.split()
588
+ .str[2]
589
+ .astype(int)
590
+ )
591
+
592
+ rounds["TD absorbed"] = (
593
+ rounds["Fighter 2 TD"]
594
+ .str.split()
595
+ .str[0]
596
+ .astype(int)
597
+ )
598
+
599
+ rounds["Opp TD att"] = (
600
+ rounds["Fighter 2 TD"]
601
+ .str.split()
602
+ .str[2]
603
+ .astype(int)
604
+ )
605
+
606
+ rounds["Sub att"] = rounds["Fighter 1 Sub Att"]
607
+
608
+ statistic["TD Avg"] = statistic["Date"].apply(
609
+ lambda d: rounds.loc[
610
+ rounds["Date"].dt.date < d,
611
+ "Td"
612
+ ].sum()
613
+ )
614
+
615
+ statistic["TD Avg"] = (
616
+ statistic["TD Avg"] /
617
+ statistic["Fight Time"] * 15
618
+ )
619
+
620
+ statistic["TD landed"] = statistic["Date"].apply(
621
+ lambda d: rounds.loc[
622
+ rounds["Date"].dt.date < d,
623
+ "TD landed"
624
+ ].sum()
625
+ )
626
+
627
+ statistic["TD att"] = statistic["Date"].apply(
628
+ lambda d: rounds.loc[
629
+ rounds["Date"].dt.date < d,
630
+ "TD att"
631
+ ].sum()
632
+ )
633
+
634
+ statistic["TD absorbed"] = statistic["Date"].apply(
635
+ lambda d: rounds.loc[
636
+ rounds["Date"].dt.date < d,
637
+ "TD absorbed"
638
+ ].sum()
639
+ )
640
+
641
+ statistic["Opp TD att"] = statistic["Date"].apply(
642
+ lambda d: rounds.loc[
643
+ rounds["Date"].dt.date < d,
644
+ "Opp TD att"
645
+ ].sum()
646
+ )
647
+
648
+ statistic["TD Acc"] = np.where(
649
+ statistic["TD att"] > 0,
650
+ statistic["TD landed"] /
651
+ statistic["TD att"],
652
+ np.nan
653
+ )
654
+
655
+ statistic["TD Def"] = np.where(
656
+ statistic["Opp TD att"] > 0,
657
+ 1 - (
658
+ statistic["TD absorbed"] /
659
+ statistic["Opp TD att"]
660
+ ),
661
+ np.nan
662
+ )
663
+
664
+ statistic["Sub Avg"] = statistic["Date"].apply(
665
+ lambda d: rounds.loc[
666
+ rounds["Date"].dt.date < d,
667
+ "Sub att"
668
+ ].sum()
669
+ )
670
+
671
+ statistic["Sub Avg"] = (
672
+ statistic["Sub Avg"] /
673
+ statistic["Fight Time"] * 15
674
+ )
675
+
676
+ statistic = statistic.drop(
677
+ columns=[
678
+ "Sig landed",
679
+ "Sig att",
680
+ "Strikes absorbed",
681
+ "Opp sig att",
682
+ "TD landed",
683
+ "TD att",
684
+ "TD absorbed",
685
+ "Opp TD att"
686
+ ]
687
+ )
688
+
689
+ statistic.columns = statistic.columns.str.replace(
690
+ "Fighter 1",
691
+ "Fighter",
692
+ regex=False
693
+ )
694
+
695
+ statistic = statistic.reset_index(drop=True)
696
+
697
+ current_statistic = statistic.iloc[[0]].copy()
698
+ current_statistic["Date"] = np.nan
699
+ past_statistic = statistic.iloc[1:].reset_index(drop=True)
700
+
701
+ return (current_statistic, past_statistic)
@@ -1,3 +0,0 @@
1
- from .data import get_data
2
- from .search import search
3
- from .ratings import get_elo
File without changes
File without changes
File without changes
File without changes
File without changes