Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7,247 changes: 3,712 additions & 3,535 deletions data/external_data/raw_fighter_details.csv

Large diffs are not rendered by default.

12,409 changes: 6,276 additions & 6,133 deletions data/merged_stats_n_scorecards/merged_stats_n_scorecards.csv

Large diffs are not rendered by default.

12,831 changes: 6,487 additions & 6,344 deletions data/stats/stats_processed.csv

Large diffs are not rendered by default.

13,182 changes: 6,664 additions & 6,518 deletions data/stats/stats_processed_all_bouts.csv

Large diffs are not rendered by default.

12,408 changes: 6,277 additions & 6,131 deletions data/stats/stats_raw.csv

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions src/data_processing/stats_update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import annotations

import pandas as pd

from .stats_processing import ensure_fight_outcome


FIGHT_IDENTITY_COLUMNS = [
"red_fighter_name",
"blue_fighter_name",
"event_date",
"event_name",
"method",
"round",
"time",
]


def merge_incremental_fights(
existing: pd.DataFrame,
incremental: pd.DataFrame,
) -> pd.DataFrame:
"""Merge newly scraped fights without collapsing same-event rematches.

Fighter pair, event, and date are not a unique bout key: UFC Ultimate
Japan contained two Kazushi Sakuraba vs. Marcus Silveira bouts on the
same card. Method, round, and time provide the discriminator available in
the tracked schema until UFCStats fight IDs are stored explicitly.
"""

existing = ensure_fight_outcome(existing)
incremental = ensure_fight_outcome(incremental)
combined = pd.concat([incremental, existing], ignore_index=True, sort=False)
combined = combined.drop_duplicates(subset=FIGHT_IDENTITY_COLUMNS, keep="first")
combined["_event_date_sort"] = pd.to_datetime(
combined["event_date"], dayfirst=True, errors="raise"
)
combined = combined.sort_values(
["_event_date_sort", "event_name", "red_fighter_name", "blue_fighter_name"],
ascending=[False, True, True, True],
kind="stable",
).drop(columns="_event_date_sort")
return combined.reset_index(drop=True)
31 changes: 31 additions & 0 deletions tests/data_processing/test_stats_update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import pandas as pd

from src.data_processing.stats_update import merge_incremental_fights


def _fight(method: str, round_: str, time: str) -> dict[str, str]:
return {
"red_fighter_name": "KAZUSHI SAKURABA",
"blue_fighter_name": "MARCUS SILVEIRA",
"event_date": "21/12/1997",
"event_name": "UFC - Ultimate Japan",
"red_fighter_result": "NC" if method == "Overturned" else "W",
"blue_fighter_result": "NC" if method == "Overturned" else "L",
"method": method,
"round": round_,
"time": time,
}


def test_merge_incremental_fights_preserves_same_event_rematch() -> None:
no_contest = _fight("Overturned", "1", "1:51")
rematch = _fight("Submission", "1", "3:44")

existing = pd.DataFrame([no_contest, rematch])
incremental = pd.DataFrame([rematch])

merged = merge_incremental_fights(existing, incremental)

assert len(merged) == 2
assert set(merged["fight_outcome"]) == {"no_contest", "red_win"}
assert set(merged["method"]) == {"Overturned", "Submission"}