Spaces:
Runtime error
Runtime error
wip(formula1_databases): create_data_analysis_views
Browse files- notebooks/formula1_databases.py +132 -1
notebooks/formula1_databases.py
CHANGED
@@ -148,6 +148,9 @@ class FastF1ToSQL:
|
|
148 |
self.insert_telemetry(session)
|
149 |
self.insert_weather(session)
|
150 |
|
|
|
|
|
|
|
151 |
# Commit changes and close connection
|
152 |
self.conn.commit()
|
153 |
self.conn.close()
|
@@ -268,6 +271,7 @@ class FastF1ToSQL:
|
|
268 |
Args:
|
269 |
session (Session): The FastF1 session object.
|
270 |
"""
|
|
|
271 |
telemetry_data_list = []
|
272 |
|
273 |
for driver in session.drivers:
|
@@ -371,8 +375,135 @@ class FastF1ToSQL:
|
|
371 |
(self.cursor.lastrowid, driver, lap['LapNumber']))
|
372 |
return self.cursor.fetchone()[0]
|
373 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
374 |
|
375 |
# Usage example:
|
376 |
session = fastf1.get_session(2023, 'Bahrain', 'Q')
|
377 |
-
converter = FastF1ToSQL('
|
378 |
converter.process_session(session)
|
|
|
148 |
self.insert_telemetry(session)
|
149 |
self.insert_weather(session)
|
150 |
|
151 |
+
# Create data analysis views
|
152 |
+
self.create_data_analysis_views()
|
153 |
+
|
154 |
# Commit changes and close connection
|
155 |
self.conn.commit()
|
156 |
self.conn.close()
|
|
|
271 |
Args:
|
272 |
session (Session): The FastF1 session object.
|
273 |
"""
|
274 |
+
print('> Inserting telemetry data...')
|
275 |
telemetry_data_list = []
|
276 |
|
277 |
for driver in session.drivers:
|
|
|
375 |
(self.cursor.lastrowid, driver, lap['LapNumber']))
|
376 |
return self.cursor.fetchone()[0]
|
377 |
|
378 |
+
def create_data_analysis_views(self) -> None:
|
379 |
+
"""Create data analysis views in the database."""
|
380 |
+
print('> Creating data analysis views...')
|
381 |
+
self.cursor.executescript('''
|
382 |
+
-- 1. Driver Performance Summary with Weather
|
383 |
+
CREATE VIEW IF NOT EXISTS DriverPerformanceSummaryWithWeather AS
|
384 |
+
SELECT
|
385 |
+
l.driver_name,
|
386 |
+
e.event_name,
|
387 |
+
s.session_type,
|
388 |
+
t.track_name,
|
389 |
+
COUNT(l.lap_id) AS total_laps,
|
390 |
+
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
391 |
+
MIN(l.lap_time_in_seconds) AS best_lap_time,
|
392 |
+
AVG(l.sector_1_time_in_seconds) AS avg_sector1_time,
|
393 |
+
AVG(l.sector_2_time_in_seconds) AS avg_sector2_time,
|
394 |
+
AVG(l.sector_3_time_in_seconds) AS avg_sector3_time,
|
395 |
+
AVG(l.finish_line_speed_trap_in_km) AS avg_finish_line_speed,
|
396 |
+
COUNT(CASE WHEN l.is_personal_best THEN 1 END) AS personal_best_laps,
|
397 |
+
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
398 |
+
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
399 |
+
SUM(CASE WHEN w.is_raining THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS rain_percentage
|
400 |
+
FROM Laps l
|
401 |
+
JOIN Sessions s ON l.session_id = s.session_id
|
402 |
+
JOIN Tracks t ON s.track_id = t.track_id
|
403 |
+
JOIN Event e ON s.event_id = e.event_id
|
404 |
+
LEFT JOIN Weather w ON s.session_id = w.session_id
|
405 |
+
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
406 |
+
GROUP BY l.driver_name, e.event_id, s.session_id;
|
407 |
+
|
408 |
+
-- 2. Tyre Performance Analysis with Weather
|
409 |
+
CREATE VIEW IF NOT EXISTS TyrePerformanceAnalysisWithWeather AS
|
410 |
+
SELECT
|
411 |
+
l.driver_name,
|
412 |
+
e.event_name,
|
413 |
+
s.session_type,
|
414 |
+
t.track_name,
|
415 |
+
l.tyre_compound,
|
416 |
+
AVG(l.tyre_life_in_laps) AS avg_tyre_life,
|
417 |
+
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
418 |
+
AVG(l.longest_strait_speed_trap_in_km) AS avg_top_speed,
|
419 |
+
COUNT(CASE WHEN l.is_fresh_tyre THEN 1 END) AS fresh_tyre_laps,
|
420 |
+
COUNT(CASE WHEN NOT l.is_fresh_tyre THEN 1 END) AS used_tyre_laps,
|
421 |
+
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
422 |
+
AVG(w.air_temperature_in_celsius) AS avg_air_temp
|
423 |
+
FROM Laps l
|
424 |
+
JOIN Sessions s ON l.session_id = s.session_id
|
425 |
+
JOIN Tracks t ON s.track_id = t.track_id
|
426 |
+
JOIN Event e ON s.event_id = e.event_id
|
427 |
+
LEFT JOIN Weather w ON s.session_id = w.session_id
|
428 |
+
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
429 |
+
GROUP BY l.driver_name, e.event_id, s.session_id, l.tyre_compound;
|
430 |
+
|
431 |
+
-- 3. Weather Impact Analysis
|
432 |
+
CREATE VIEW IF NOT EXISTS WeatherImpactAnalysis AS
|
433 |
+
SELECT
|
434 |
+
e.event_name,
|
435 |
+
s.session_type,
|
436 |
+
t.track_name,
|
437 |
+
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
438 |
+
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
439 |
+
AVG(w.relative_air_humidity_in_percentage) AS avg_humidity,
|
440 |
+
AVG(w.wind_speed_in_meters_per_seconds) AS avg_wind_speed,
|
441 |
+
SUM(CASE WHEN w.is_raining THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS rain_percentage,
|
442 |
+
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
443 |
+
MIN(l.lap_time_in_seconds) AS best_lap_time
|
444 |
+
FROM Weather w
|
445 |
+
JOIN Sessions s ON w.session_id = s.session_id
|
446 |
+
JOIN Tracks t ON s.track_id = t.track_id
|
447 |
+
JOIN Event e ON s.event_id = e.event_id
|
448 |
+
JOIN Laps l ON s.session_id = l.session_id
|
449 |
+
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
450 |
+
GROUP BY e.event_id, s.session_id;
|
451 |
+
|
452 |
+
-- 4. Event Performance Overview
|
453 |
+
CREATE VIEW IF NOT EXISTS EventPerformanceOverview AS
|
454 |
+
SELECT
|
455 |
+
e.event_name,
|
456 |
+
e.country,
|
457 |
+
e.location,
|
458 |
+
s.session_type,
|
459 |
+
COUNT(DISTINCT l.driver_name) AS driver_count,
|
460 |
+
AVG(l.lap_time_in_seconds) AS avg_lap_time,
|
461 |
+
MIN(l.lap_time_in_seconds) AS best_lap_time,
|
462 |
+
MAX(l.finish_line_speed_trap_in_km) AS max_finish_line_speed,
|
463 |
+
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
464 |
+
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
465 |
+
SUM(CASE WHEN w.is_raining THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS rain_percentage
|
466 |
+
FROM Event e
|
467 |
+
JOIN Sessions s ON e.event_id = s.event_id
|
468 |
+
JOIN Laps l ON s.session_id = l.session_id
|
469 |
+
LEFT JOIN Weather w ON s.session_id = w.session_id
|
470 |
+
AND l.lap_start_time_in_datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
471 |
+
GROUP BY e.event_id, s.session_id;
|
472 |
+
|
473 |
+
-- 5. Telemetry Analysis with Weather
|
474 |
+
CREATE VIEW IF NOT EXISTS TelemetryAnalysisWithWeather AS
|
475 |
+
SELECT
|
476 |
+
l.lap_id,
|
477 |
+
l.driver_name,
|
478 |
+
e.event_name,
|
479 |
+
s.session_type,
|
480 |
+
t.track_name,
|
481 |
+
l.lap_number,
|
482 |
+
l.lap_time_in_seconds,
|
483 |
+
AVG(tel.speed_in_km) AS avg_speed,
|
484 |
+
MAX(tel.speed_in_km) AS max_speed,
|
485 |
+
AVG(tel.RPM) AS avg_RPM,
|
486 |
+
MAX(tel.RPM) AS max_RPM,
|
487 |
+
AVG(tel.throttle_input) AS avg_throttle,
|
488 |
+
SUM(CASE WHEN tel.is_brake_pressed THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS brake_percentage,
|
489 |
+
SUM(CASE WHEN tel.is_DRS_open THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS drs_usage_percentage,
|
490 |
+
SUM(CASE WHEN tel.is_off_track THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS off_track_percentage,
|
491 |
+
AVG(w.air_temperature_in_celsius) AS avg_air_temp,
|
492 |
+
AVG(w.track_temperature_in_celsius) AS avg_track_temp,
|
493 |
+
AVG(w.wind_speed_in_meters_per_seconds) AS avg_wind_speed
|
494 |
+
FROM Laps l
|
495 |
+
JOIN Sessions s ON l.session_id = s.session_id
|
496 |
+
JOIN Tracks t ON s.track_id = t.track_id
|
497 |
+
JOIN Event e ON s.event_id = e.event_id
|
498 |
+
JOIN Telemetry tel ON l.lap_id = tel.lap_id
|
499 |
+
LEFT JOIN Weather w ON s.session_id = w.session_id
|
500 |
+
AND tel.datetime BETWEEN w.datetime AND datetime(w.datetime, '+5 minutes')
|
501 |
+
GROUP BY l.lap_id;
|
502 |
+
''')
|
503 |
+
self.conn.commit()
|
504 |
+
|
505 |
|
506 |
# Usage example:
|
507 |
session = fastf1.get_session(2023, 'Bahrain', 'Q')
|
508 |
+
converter = FastF1ToSQL('Bahrain_2023_Q.db')
|
509 |
converter.process_session(session)
|