File size: 2,457 Bytes
c8a8b27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
"""Load and clean the raw violation data into a tidy parking-records frame."""
import ast
import json

import pandas as pd

from src import config


def _parse_list(x):
    """`violation_type` arrives as a JSON-ish string like ["NO PARKING"]."""
    if isinstance(x, list):
        return x
    if not isinstance(x, str) or not x.strip():
        return []
    try:
        return json.loads(x)
    except Exception:
        try:
            return ast.literal_eval(x)
        except Exception:
            return []


def record_severity(violations):
    """Max flow-disruption weight across a record's violations (0 if none parking)."""
    return max((config.PARKING_SEVERITY.get(v, 0.0) for v in violations), default=0.0)


def _is_peak(hour):
    return any(lo <= hour < hi for lo, hi in config.PEAK_WINDOWS)


def load_clean():
    """Return one row per parking violation with engineered time/severity fields."""
    df = pd.read_csv(config.DATA_RAW, low_memory=False)

    # --- coordinates: drop missing / out-of-Bengaluru ---
    df = df.dropna(subset=["latitude", "longitude"])
    df = df[df["latitude"].between(config.LAT_MIN, config.LAT_MAX)
            & df["longitude"].between(config.LON_MIN, config.LON_MAX)].copy()

    # --- timestamps -> IST ---
    df["created_dt"] = pd.to_datetime(df["created_datetime"], errors="coerce", utc=True)
    df = df.dropna(subset=["created_dt"]).copy()
    df["ts"] = df["created_dt"].dt.tz_convert(config.TZ)
    df["date"] = df["ts"].dt.date
    df["hour"] = df["ts"].dt.hour
    df["dow"] = df["ts"].dt.dayofweek
    df["month"] = df["ts"].dt.month
    df["is_peak"] = df["hour"].apply(_is_peak)

    # --- violations & severity ---
    df["violations"] = df["violation_type"].apply(_parse_list)
    df["severity"] = df["violations"].apply(record_severity)
    df = df[df["severity"] > 0].copy()          # keep only parking-relevant records

    # --- junction presence ---
    df["junction_name"] = df["junction_name"].fillna("No Junction")
    df["has_junction"] = (df["junction_name"].str.strip().str.lower() != "no junction")

    keep = ["id", "latitude", "longitude", "location", "police_station",
            "junction_name", "has_junction", "vehicle_type", "vehicle_number", "violations",
            "severity", "ts", "date", "hour", "dow", "month", "is_peak"]
    return df[keep].reset_index(drop=True)


if __name__ == "__main__":
    d = load_clean()
    print(d.shape)
    print(d.head())