Spaces:
Sleeping
Sleeping
anshumanSingh-tech
Update dataset with complete IPL 2026 season, fix dashboard bugs, improve ML features
1c7a005 | import pandas as pd | |
| import numpy as np | |
| from pathlib import Path | |
| RAW = Path("E:/ipl-analytics/data/raw") | |
| PROCESSED = Path("E:/ipl-analytics/data/processed") | |
| PROCESSED.mkdir(parents=True, exist_ok=True) | |
| TEAM_NAME_MAP = { | |
| "Rising Pune Supergiant" : "Rising Pune Supergiants", | |
| "King XI Punjab" : "Punjab Kings", | |
| "Pune Warriors" : "Pune Warriors India", | |
| "Deccan Chargrers" : "Sunrisers Hyderabad", | |
| "Delhi Daredevils" : "Delhi Capitals", | |
| "Royal Challengers Bengaluru" : "Royal Challengers Bangalore", | |
| } | |
| VENUE_KEYWORDS = { | |
| "Wankhede": "Wankhede Stadium", | |
| "Chinnaswamy": "M Chinnaswamy Stadium", | |
| "Chidambaram": "MA Chidambaram Stadium", | |
| "Chepauk": "MA Chidambaram Stadium", | |
| "Eden Gardens": "Eden Gardens", | |
| "Arun Jaitley": "Feroz Shah Kotla", | |
| "Feroz Shah Kotla": "Feroz Shah Kotla", | |
| "Rajasekhara": "Vizag Stadium", | |
| "Yadavindra": "Mullanpur Stadium", | |
| "Ekana": "Ekana Stadium", | |
| "Rajiv Gandhi": "Uppal Stadium", | |
| "IS Bindra": "PCA Stadium", | |
| "Mohali": "PCA Stadium", | |
| "Narendra Modi": "Motera Stadium", | |
| "Dy Patil": "DY Patil Stadium", | |
| "Brabourne": "Brabourne Stadium", | |
| } | |
| IPL_VALID_SEASONS = set(range(2008, 2025)) | |
| import datetime | |
| IPL_VALID_SEASONS = set(range(2008, datetime.date.today().year + 1)) | |
| SLASH_SEASON_MAP = { | |
| "2007/08" : 2008, | |
| "2009/10" : 2010, | |
| "2020/21" : 2020, | |
| } | |
| def clean_matches(matches: pd.DataFrame) -> pd.DataFrame: | |
| df = matches.copy() | |
| if "id" in df.columns: | |
| df = df.rename(columns={"id": "match_id"}) | |
| df["date"] = pd.to_datetime(df["date"], errors="coerce") | |
| def fix_season(val): | |
| val = str(val).strip() | |
| if val in SLASH_SEASON_MAP: | |
| return SLASH_SEASON_MAP[val] | |
| if "/" in val: | |
| parts = val.split("/") | |
| suffix = parts[1].strip() | |
| prefix = parts[0].strip()[:2] | |
| return int(prefix + suffix) | |
| val_clean = val.replace("IPL", "").replace("Season", "").strip() | |
| year = int(float(val_clean)) | |
| if year == 2007: | |
| return 2008 | |
| return year | |
| df["season"] = df["season"].apply(fix_season).astype("int32") | |
| detected = set(df["season"].unique()) | |
| unexpected = detected - IPL_VALID_SEASONS | |
| missing = IPL_VALID_SEASONS - detected | |
| if unexpected: | |
| print(f"WARNING β unexpected seasons found : {sorted(unexpected)}") | |
| print(f" Dropping {len(df[df['season'].isin(unexpected)])} rows.") | |
| df = df[df["season"].isin(IPL_VALID_SEASONS)].copy() | |
| else: | |
| print("OK β all seasons are valid IPL years.") | |
| if missing: | |
| print(f"INFO β seasons not in dataset : {sorted(missing)}") | |
| print(f" Expected if your CSV doesn't cover those years yet.") | |
| else: | |
| print("OK β all expected IPL seasons are present.") | |
| print(f"\nSeason distribution : {sorted(df['season'].unique())}") | |
| print(f"Season range : {df['season'].min()} β {df['season'].max()}") | |
| print(f"Total seasons : {df['season'].nunique()}") | |
| print(f"Total matches : {len(df)}") | |
| df["venue"] = df["venue"].astype(str).str.strip() | |
| for keyword, clean_name in VENUE_KEYWORDS.items(): | |
| mask = df["venue"].str.contains(keyword, case=False, na=False) | |
| df.loc[mask, "venue"] = clean_name | |
| for col in ["result_margin", "dl_applied", "target_runs"]: | |
| if col in df.columns: | |
| df[col] = pd.to_numeric(df[col], errors="coerce").fillna(0).astype(int) | |
| for col in ["team1", "team2", "winner", "toss_winner"]: | |
| if col in df.columns: | |
| df[col] = df[col].replace(TEAM_NAME_MAP) | |
| df["player_of_match"] = df["player_of_match"].fillna("N/A") | |
| def result_type(row): | |
| r = str(row.get("result", "")).lower().strip() | |
| if r == "runs": return "runs" | |
| if r == "wickets": return "wickets" | |
| return "no_result" | |
| df["result_type"] = df.apply(result_type, axis=1) | |
| df["is_no_result"] = df["winner"].isna().astype(int) | |
| df["winner"] = df["winner"].fillna("No Result") | |
| df["day_of_week"] = df["date"].dt.day_name() | |
| df["month"] = df["date"].dt.month | |
| df = df.sort_values(["season", "date"]).reset_index(drop=True) | |
| print(f"\nclean_matches done: {matches.shape} β {df.shape}") | |
| remaining_nulls = df.isnull().sum() | |
| remaining_nulls = remaining_nulls[remaining_nulls > 0] | |
| if len(remaining_nulls): | |
| print(f"Remaining nulls:\n{remaining_nulls.to_string()}") | |
| else: | |
| print("No nulls remaining.") | |
| return df | |
| def clean_deliveries(deliveries: pd.DataFrame) -> pd.DataFrame: | |
| df = deliveries.copy() | |
| df = df.rename(columns={ | |
| "batter": "batsman", | |
| }) | |
| for col in ["batting_team", "bowling_team"]: | |
| if col in df.columns: | |
| df[col] = df[col].replace(TEAM_NAME_MAP) | |
| num_cols = ["inning", "over", "ball", "batsman_runs", "extra_runs", "total_runs"] | |
| for col in num_cols: | |
| if col in df.columns: | |
| df[col] = pd.to_numeric(df[col], errors="coerce").fillna(0).astype(int) | |
| df["is_wide"] = (df["extras_type"] == "wides").astype(int) | |
| df["is_noball"] = (df["extras_type"] == "noballs").astype(int) | |
| for col in ["batting_team", "bowling_team"]: | |
| df[col] = df[col].replace(TEAM_NAME_MAP) | |
| df["player_dismissed"] = df["player_dismissed"].fillna("not_out") | |
| df["dismissal_kind"] = df["dismissal_kind"].fillna("not_out") | |
| df["is_wicket"] = df["is_wicket"].fillna(0).astype(int) | |
| df["is_four"] = (df["batsman_runs"] == 4).astype(int) | |
| df["is_six"] = (df["batsman_runs"] == 6).astype(int) | |
| df["is_dot_ball"] = ( | |
| (df["batsman_runs"] == 0) & | |
| (df["is_wide"] == 0) & | |
| (df["is_noball"] == 0) | |
| ).astype(int) | |
| def over_phase(over): | |
| if over <= 6: return "powerplay" | |
| if over <= 15: return "middle" | |
| return "death" | |
| df["over_phase"] = df["over"].apply(over_phase) | |
| df["is_legal_delivery"] = ((df["is_wide"] == 0) & (df["is_noball"] == 0)).astype(int) | |
| df = df.sort_values(["match_id", "inning", "over", "ball"]).reset_index(drop=True) | |
| print(f"\nclean_deliveries: {deliveries.shape} β {df.shape}") | |
| print(f" Nulls remaining:\n{df.isnull().sum()[df.isnull().sum()>0].to_string()}") | |
| return df |