The Driver class in tif1 provides driver-specific access to lap data, telemetry, and metadata. Each driver is represented as a pandas Series containing their information (name, team, number) with methods to access their session data.
class Driver(pd.Series): """ Represents a driver in a session as a pandas Series. Args: session: Parent Session object driver: Driver code (e.g., 'VER', 'HAM') Attributes: session: Parent Session driver: Driver code laps: DataFrame with driver's laps """
session = tif1.get_session(2024, "Monaco", "Race")laps = session.laps# Get all laps for a driverver_laps = laps.pick_driver('VER')print(f"Verstappen completed {len(ver_laps)} laps")# Get laps for multiple driverstop3_laps = laps.pick_drivers(['VER', 'HAM', 'LEC'])print(f"Top 3 drivers: {len(top3_laps)} total laps")
For loading telemetry for multiple drivers efficiently:
session = tif1.get_session(2024, "Monaco", "Qualifying")# ✅ Fast - parallel loading for all driversfastest_tels = session.get_fastest_laps_tels(by_driver=True)# Returns DataFrame with all drivers' fastest lap telemetry# ✅ Fast - specific drivers onlytop3_tels = session.get_fastest_laps_tels( by_driver=True, drivers=['VER', 'HAM', 'LEC'])
The get_fastest_laps_tels() method loads telemetry in parallel, making it 28x faster than sequential loading (11.2s → 0.4s for 19 drivers).
# All of these workver1 = laps.pick_driver('VER') # Driver codever2 = laps.pick_driver('1') # Driver number (string)ver3 = laps.pick_driver(1) # Driver number (int)# Even dict-like objectsdriver_dict = {'driver': 'VER', 'dn': 1}ver4 = laps.pick_driver(driver_dict)
From core.py:282-306:
@staticmethoddef _normalize_driver_identifier(identifier: Any) -> str: """Normalize various driver identifier formats to string.""" if isinstance(identifier, str | int): return str(identifier) if isinstance(identifier, dict): for key in ('driver', 'Driver', 'Abbreviation', 'dn', 'RacingNumber'): value = identifier.get(key) if value is not None and str(value).strip(): return str(value) if hasattr(identifier, 'driver'): value = identifier.driver if value is not None and str(value).strip(): return str(value) return str(identifier)
session = tif1.get_session(2024, "Monaco", "Race")# Get all resultsresults = session.resultsprint(results[['FullName', 'TeamName', 'Position', 'Points']])# Get specific driver resultver_result = results[results['Abbreviation'] == 'VER'].iloc[0]print(f"{ver_result['FullName']}: P{ver_result['Position']}")# Check DNF statusif ver_result.dnf: print(f"{ver_result['FullName']} did not finish")
ver_laps = laps.pick_driver('VER')# Get final stint on soft tiressoft_stint = ver_laps[ver_laps['Compound'] == 'SOFT']if len(soft_stint) > 5: # Compare first 3 laps vs last 3 laps early_pace = soft_stint.head(3)['LapTime'].mean() late_pace = soft_stint.tail(3)['LapTime'].mean() degradation = (late_pace - early_pace).total_seconds() print(f"Tire degradation: {degradation:.2f}s over {len(soft_stint)} laps")
# ✅ Good - get drivers oncedrivers = session.driversfor driver in drivers: driver_laps = laps.pick_driver(driver) # process laps...# ❌ Bad - repeated property accessfor i in range(len(session.drivers)): driver = session.drivers[i] # Re-fetches each time