UFCData 0.4.0__tar.gz → 0.5.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.
- {ufcdata-0.4.0 → ufcdata-0.5.0}/PKG-INFO +1 -1
- {ufcdata-0.4.0 → ufcdata-0.5.0}/README.md +29 -74
- {ufcdata-0.4.0 → ufcdata-0.5.0}/UFCData.egg-info/PKG-INFO +1 -1
- {ufcdata-0.4.0 → ufcdata-0.5.0}/UFCData.egg-info/SOURCES.txt +1 -0
- {ufcdata-0.4.0 → ufcdata-0.5.0}/pyproject.toml +1 -1
- ufcdata-0.5.0/ufcdata/__init__.py +5 -0
- ufcdata-0.5.0/ufcdata/helper.py +145 -0
- ufcdata-0.4.0/ufcdata/__init__.py +0 -4
- {ufcdata-0.4.0 → ufcdata-0.5.0}/LICENSE.md +0 -0
- {ufcdata-0.4.0 → ufcdata-0.5.0}/UFCData.egg-info/dependency_links.txt +0 -0
- {ufcdata-0.4.0 → ufcdata-0.5.0}/UFCData.egg-info/requires.txt +0 -0
- {ufcdata-0.4.0 → ufcdata-0.5.0}/UFCData.egg-info/top_level.txt +0 -0
- {ufcdata-0.4.0 → ufcdata-0.5.0}/setup.cfg +0 -0
- {ufcdata-0.4.0 → ufcdata-0.5.0}/ufcdata/data.py +0 -0
- {ufcdata-0.4.0 → ufcdata-0.5.0}/ufcdata/fighter.py +0 -0
- {ufcdata-0.4.0 → ufcdata-0.5.0}/ufcdata/ratings.py +0 -0
- {ufcdata-0.4.0 → ufcdata-0.5.0}/ufcdata/search.py +0 -0
|
@@ -9,6 +9,7 @@ add helper functions like convert odds
|
|
|
9
9
|
## Table of Contents
|
|
10
10
|
|
|
11
11
|
- [Installation](#installation)
|
|
12
|
+
- [Updating the Package](#updating-the-package)
|
|
12
13
|
|
|
13
14
|
Accessing Data
|
|
14
15
|
- [Loading Data](#loading-data)
|
|
@@ -19,7 +20,7 @@ Rating Function
|
|
|
19
20
|
|
|
20
21
|
Fighter Functions
|
|
21
22
|
- [Fighter History](#fighter-history)
|
|
22
|
-
- [Fighter Statistic](#fighter-
|
|
23
|
+
- [Fighter Statistic](#fighter-statistic)
|
|
23
24
|
|
|
24
25
|
Helper Functions
|
|
25
26
|
- [Odds Convert](#elo)
|
|
@@ -41,6 +42,12 @@ Data Sources
|
|
|
41
42
|
pip install ufcdata
|
|
42
43
|
```
|
|
43
44
|
|
|
45
|
+
## Updating the Package
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install --no-cache-dir --upgrade ufcdata
|
|
49
|
+
```
|
|
50
|
+
|
|
44
51
|
## Loading Data
|
|
45
52
|
|
|
46
53
|
```python
|
|
@@ -192,7 +199,7 @@ jon_jones_history = ufc.get_fighter_history(
|
|
|
192
199
|
|
|
193
200
|
This function is useful for analyzing an individual fighter's career, constructing fighter-level features, or preparing historical data for predictive modeling.
|
|
194
201
|
|
|
195
|
-
## Fighter
|
|
202
|
+
## Fighter Statistic
|
|
196
203
|
|
|
197
204
|
|
|
198
205
|
The function `get_fighter_statistic()`, transforms a fighter's UFC fight history into a time-series dataset where each row represents the fighter's statistics **as they were known before a particular fight**.
|
|
@@ -276,85 +283,33 @@ This makes the data suitable for constructing historical features for a predicti
|
|
|
276
283
|
### Example
|
|
277
284
|
|
|
278
285
|
```python
|
|
279
|
-
|
|
280
|
-
fighter_link=fighter_link,
|
|
281
|
-
fighter_bio=fighter_bio,
|
|
282
|
-
fights_df=fights_df,
|
|
283
|
-
rounds_df=rounds_df,
|
|
284
|
-
)
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
## Data Requirements
|
|
289
|
-
|
|
290
|
-
The function expects the input DataFrames to contain the relevant fighter, fight, and round-level information.
|
|
291
|
-
|
|
292
|
-
### `fighter_bio`
|
|
293
|
-
|
|
294
|
-
Must contain at least:
|
|
295
|
-
|
|
296
|
-
```text
|
|
297
|
-
Name
|
|
298
|
-
Fighter Link
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### `fights_df`
|
|
302
|
-
|
|
303
|
-
Must contain fighter links, outcomes, fight dates, and fight metadata required by the function.
|
|
304
|
-
|
|
305
|
-
### `rounds_df`
|
|
306
|
-
|
|
307
|
-
Must contain round-level striking, takedown, submission, and control statistics.
|
|
308
|
-
|
|
309
|
-
### `future_df`
|
|
310
|
-
|
|
311
|
-
Must contain:
|
|
286
|
+
import ufcdata as ufc
|
|
312
287
|
|
|
313
|
-
|
|
314
|
-
Date
|
|
315
|
-
```
|
|
288
|
+
data = ufc.get_data()
|
|
316
289
|
|
|
317
|
-
|
|
290
|
+
fighter_bio = data["fighter_bio"].copy()
|
|
291
|
+
fights_df = data["past_fights"].copy()
|
|
292
|
+
rounds_df = data['past_rounds'].copy()
|
|
293
|
+
future_df = data['future_fights']
|
|
318
294
|
|
|
319
|
-
|
|
295
|
+
# Obtain Jon Jones' UFCStats link
|
|
296
|
+
jon_jones = ufc.search(
|
|
297
|
+
fighter_bio,
|
|
298
|
+
"Name",
|
|
299
|
+
"Jon Jones"
|
|
300
|
+
).iloc[0]["Fighter Link"]
|
|
320
301
|
|
|
321
|
-
|
|
302
|
+
# Get Jon Jones' statistic
|
|
303
|
+
jon_jones_current, jon_jones_past = ufc.get_fighter_statistic(
|
|
304
|
+
jon_jones,
|
|
305
|
+
fighter_bio,
|
|
306
|
+
fights_df,
|
|
307
|
+
rounds_df
|
|
308
|
+
)
|
|
322
309
|
|
|
323
|
-
|
|
324
|
-
Fighter
|
|
325
|
-
│
|
|
326
|
-
▼
|
|
327
|
-
Retrieve fight history
|
|
328
|
-
│
|
|
329
|
-
▼
|
|
330
|
-
Construct chronological fight history
|
|
331
|
-
│
|
|
332
|
-
▼
|
|
333
|
-
Calculate UFC record
|
|
334
|
-
│
|
|
335
|
-
▼
|
|
336
|
-
Calculate Elo ratings
|
|
337
|
-
│
|
|
338
|
-
▼
|
|
339
|
-
Calculate cumulative fight statistics
|
|
340
|
-
│
|
|
341
|
-
├── Striking
|
|
342
|
-
├── Takedowns
|
|
343
|
-
└── Submissions
|
|
344
|
-
│
|
|
345
|
-
▼
|
|
346
|
-
Generate pre-fight statistics
|
|
347
|
-
│
|
|
348
|
-
├── Past fights
|
|
349
|
-
└── Upcoming fight
|
|
350
|
-
│
|
|
351
|
-
▼
|
|
352
|
-
Return current_statistic, past_statistic
|
|
310
|
+
jon_jones_current
|
|
353
311
|
```
|
|
354
312
|
|
|
355
|
-
The resulting data can then be combined with opponent statistics and other fight-level features to create inputs for UFC fight prediction models.
|
|
356
|
-
|
|
357
|
-
|
|
358
313
|
|
|
359
314
|
## Online Sources
|
|
360
315
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
def convert_odds(odds, probability=False):
|
|
6
|
+
"""
|
|
7
|
+
Convert American betting odds to a numeric value or implied probability.
|
|
8
|
+
|
|
9
|
+
Parameters
|
|
10
|
+
----------
|
|
11
|
+
odds : str, int, float, or None
|
|
12
|
+
American betting odds. The function extracts the first signed or
|
|
13
|
+
unsigned integer from the input. Missing values return None.
|
|
14
|
+
|
|
15
|
+
probability : bool, default=False
|
|
16
|
+
If False, return the extracted American odds as an integer.
|
|
17
|
+
If True, return the implied probability as a decimal.
|
|
18
|
+
|
|
19
|
+
Returns
|
|
20
|
+
-------
|
|
21
|
+
int or float or None
|
|
22
|
+
The extracted American odds if probability=False, otherwise the
|
|
23
|
+
implied probability. Returns None for missing values.
|
|
24
|
+
|
|
25
|
+
Examples
|
|
26
|
+
--------
|
|
27
|
+
>>> convert_odds("+120")
|
|
28
|
+
120
|
|
29
|
+
>>> convert_odds("-400")
|
|
30
|
+
-400
|
|
31
|
+
>>> convert_odds("-400", probability=True)
|
|
32
|
+
0.8
|
|
33
|
+
"""
|
|
34
|
+
if pd.isna(odds):
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
odds = int(re.search(r'[+-]?\d+', str(odds)).group())
|
|
38
|
+
|
|
39
|
+
if not probability:
|
|
40
|
+
return odds
|
|
41
|
+
|
|
42
|
+
if odds < 0:
|
|
43
|
+
return -odds / (-odds + 100)
|
|
44
|
+
else:
|
|
45
|
+
return 100 / (odds + 100)
|
|
46
|
+
|
|
47
|
+
def convert_gender(gender):
|
|
48
|
+
"""
|
|
49
|
+
Convert a gender label to a binary numeric value.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
gender : str
|
|
54
|
+
Gender label. "Male" is mapped to 1 and "Female" is mapped to 0.
|
|
55
|
+
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
int or None
|
|
59
|
+
1 for "Male", 0 for "Female", and None for unrecognized or missing values.
|
|
60
|
+
"""
|
|
61
|
+
if gender == "Male":
|
|
62
|
+
return 1
|
|
63
|
+
elif gender == "Female":
|
|
64
|
+
return 0
|
|
65
|
+
else:
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def convert_weight(weight):
|
|
70
|
+
"""
|
|
71
|
+
Convert a weight class label to its corresponding weight limit in pounds.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
weight : str
|
|
76
|
+
Weight class label to convert.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
float
|
|
81
|
+
Weight limit in pounds for recognized weight classes. Returns NaN for
|
|
82
|
+
catch weight, open weight, unrecognized weight classes, or missing values.
|
|
83
|
+
"""
|
|
84
|
+
weight_map = {
|
|
85
|
+
"Strawweight": 115,
|
|
86
|
+
"Flyweight": 125,
|
|
87
|
+
"Bantamweight": 135,
|
|
88
|
+
"Featherweight": 145,
|
|
89
|
+
"Lightweight": 155,
|
|
90
|
+
"Welterweight": 170,
|
|
91
|
+
"Middleweight": 185,
|
|
92
|
+
"Light Heavyweight": 205,
|
|
93
|
+
"Heavyweight": 265,
|
|
94
|
+
"Super Heavyweight": 265,
|
|
95
|
+
"Catch Weight": np.nan,
|
|
96
|
+
"Open Weight": np.nan,
|
|
97
|
+
}
|
|
98
|
+
return weight_map.get(weight.strip(), np.nan)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def mirror(df, cols_1, cols_2, in_order=True):
|
|
102
|
+
"""
|
|
103
|
+
Create mirrored versions of a DataFrame by swapping paired columns.
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
df : pandas.DataFrame
|
|
108
|
+
Input DataFrame to mirror.
|
|
109
|
+
cols_1 : list-like
|
|
110
|
+
Column names representing the first side of each pair.
|
|
111
|
+
cols_2 : list-like
|
|
112
|
+
Column names representing the second side of each pair. Each column
|
|
113
|
+
is swapped with the corresponding column in `cols_1`.
|
|
114
|
+
in_order : bool, default=True
|
|
115
|
+
Determines the order of rows in the returned DataFrame. If True,
|
|
116
|
+
each original row is immediately followed by its mirrored row.
|
|
117
|
+
If False, all original rows are followed by all mirrored rows.
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
pandas.DataFrame
|
|
122
|
+
DataFrame containing the original and mirrored rows.
|
|
123
|
+
|
|
124
|
+
Notes
|
|
125
|
+
-----
|
|
126
|
+
The input DataFrame is copied and is not modified in place.
|
|
127
|
+
"""
|
|
128
|
+
df = df.copy()
|
|
129
|
+
df_original = df.copy()
|
|
130
|
+
|
|
131
|
+
# Swap each pair of columns
|
|
132
|
+
for c1, c2 in zip(cols_1, cols_2):
|
|
133
|
+
temp = df[c1].copy()
|
|
134
|
+
df[c1] = df[c2]
|
|
135
|
+
df[c2] = temp
|
|
136
|
+
|
|
137
|
+
if not in_order:
|
|
138
|
+
return pd.concat([df_original, df], ignore_index=True)
|
|
139
|
+
|
|
140
|
+
rows = []
|
|
141
|
+
for r1, r2 in zip(df_original.itertuples(index=False), df.itertuples(index=False)):
|
|
142
|
+
rows.append(r1)
|
|
143
|
+
rows.append(r2)
|
|
144
|
+
|
|
145
|
+
return pd.DataFrame(rows, columns=df.columns)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|