
FastF1 入门基础掌握 Session、Event、赛果与圈速数据的 Pandas 数据操作【免费下载链接】Fast-F1FastF1 is a python package for accessing and analyzing Formula 1 results, schedules, timing data and telemetry项目地址: https://gitcode.com/GitHub_Trending/fa/Fast-F1本篇技术指南基于 FastF1 官方入门文档 docs/getting_started/basics.rst系统讲解如何加载 F1 赛季的赛事与场次Session、读取赛事信息Event与赛季日程EventSchedule并在会话数据加载Session.load后操作赛果SessionResults与圈速数据Laps。读完本文你将掌握 FastF1 中最核心、使用频率最高的数据获取链路并理解其底层基于 Pandas 的对象体系可直接上手撰写自己的 F1 数据分析脚本。从 Pandas 出发FastF1 的数据模型FastF1 的整个数据体系主要构建在 Pandas 的DataFrame与Series对象之上。如果你熟悉 Pandas拿到 FastF1 的数据后几乎可以零成本上手即使不熟悉也可以借助 Pandas 文档先补充基础。这种设计在源码中体现得非常直观仓库在 fastf1/internals/pandas_base.py 中定义了BaseDataFrame与BaseSeries作为所有数据对象的公共基类而核心业务对象全部继承自它们对象基类代表的数据fastf1.core.Session普通类封装会话一个场次练习赛、排位赛、冲刺赛、正赛fastf1.events.Eventpandas.Series一个赛事周末含多个场次fastf1.events.EventSchedulepandas.DataFrame一整年的赛事日程fastf1.core.SessionResultspandas.DataFrame单场次的赛果与车手信息fastf1.core.Lapspandas.DataFrame单场次中所有车手的所有单圈fastf1.core.Telemetrypandas.DataFrame赛车遥测数据因此你在 FastF1 中拿到的几乎每一个表格都可以直接使用iloc、loc、groupby、merge等标准 Pandas API 进行切片、筛选与聚合。Session是这一切的起点。加载会话Session一切从fastf1.get_session开始fastf1.core.Session对象是使用 FastF1 做任何事情的重要起点。通常你的第一步就是加载一个场次推荐使用fastf1.get_session import fastf1 session fastf1.get_session(2021, 7, Q) session.name Qualifying session.date Timestamp(2021-06-19 13:00:00)上面这段代码加载的是2021 赛季第 7 站法国大奖赛的排位赛Q。session.name给出场次全称session.date给出该场次的本地开始时间2021-06-19 13:00:00。从 events.py 中的函数签名 可以看到get_session接收三个核心位置参数def get_session(year, gp, identifierNone, *, backendNone, exact_matchFalse) - Sessionyear锦标赛年份整数gp赛事名称字符串或分站序号整数。传入字符串时会做模糊匹配传入整数时按第几站精确解析identifier场次标识支持缩写、完整名称或序号三种形式。会话标识符identifier一览identifier的可选值定义在 events.py 的_SESSION_TYPE_ABBREVIATIONS常量 中缩写完整名称RRaceQQualifyingSSprintSQSprint QualifyingSSSprint ShootoutFP1/FP2/FP3Practice 1 / 2 / 3此外还可以直接传完整名称如Qualifying或 1~5 的序号get_session(2021, 5, 3)表示第 5 站的第 3 场练习赛。具体的解析逻辑在Event.get_session_name中数字会映射到Session1~Session5列字符串会先尝试完整名称匹配、再按缩写表查询。同时注意Sprint在 2021、2022 年曾被命名为Sprint QualifyingFastF1 会对旧名称做静默兼容修正。重要提醒get_session不会加载任何数据get_session返回的Session对象此时只包含赛事与场次的元信息不包含计时、遥测等任何场次数据。要真正取得数据必须随后调用session.load()详见下文加载赛果一节。这一点在 get_session 的 docstring 中有明确说明。认识 Event一场赛事周末的完整信息上一节的session到底属于哪一站比赛答案在session.event属性中。Event对象持有关于每个赛事的全部信息一个 Event 通常由多个 Session 组成练习赛、排位赛、正赛等可通过 session 对象直接访问 session.event RoundNumber 7 Country France Location Le Castellet OfficialEventName FORMULA 1 EMIRATES GRAND PRIX DE FRANCE 2021 EventDate 2021-06-20 00:00:00 EventName French Grand Prix EventFormat conventional Session1 Practice 1 Session1Date 2021-06-18 11:30:0002:00 Session1DateUtc 2021-06-18 09:30:00 Session2 Practice 2 Session2Date 2021-06-18 15:00:0002:00 Session2DateUtc 2021-06-18 13:00:00 Session3 Practice 3 Session3Date 2021-06-19 12:00:0002:00 Session3DateUtc 2021-06-19 10:00:00 Session4 Qualifying Session4Date 2021-06-19 15:00:0002:00 Session4DateUtc 2021-06-19 13:00:00 Session5 Race Session5Date 2021-06-20 15:00:0002:00 Session5DateUtc 2021-06-20 13:00:00 F1ApiSupport True Name: 7, dtype: object这段输出包含了非常丰富的信息赛事标识RoundNumber第 7 站、Country、Location赛道所在地、OfficialEventName官方全名、EventName通用名、EventFormatconventional常规赛制冲刺赛周末则为sprint、sprint_shootout或sprint_qualifying等场次时间Session1~Session5依次对应 Practice 1 / 2 / 3、Qualifying、Race每场都有两列时间——SessionXDate为带时区的本地时间如2021-06-18 11:30:0002:00SessionXDateUtc为不含时区的 UTC 时间EventDate是正赛当天的日期时间归零数据支持F1ApiSupport标识该场次是否支持通过 F1 官方 API 获取计时数据2018 年及以后通常为True。Event 是 pandas.Series 的子类Event类继承自pandas.Series源码见 events.py 中的 Event 定义因此它的每个字段都可以像操作 Series 一样通过键访问 session.event[EventName] French Grand Prix session.event[EventDate] # 这是正赛当天 Timestamp(2021-06-20 00:00:00)Event还额外提供了一些面向 F1 语义的方法is_testing()判断是否为测试赛以及按场次取 Session 的便捷方法见下一节。直接加载 Event并从 Event 取回 Session除了通过session.event间接访问你还可以用fastf1.get_event直接加载一个赛事 event fastf1.get_event(2021, 7) event RoundNumber 7 Country France ...内容与上文 session.event 完全一致... F1ApiSupport True Name: 7, dtype: object session event.get_race() session.name RaceEvent对象反过来提供了获取其下属场次的方法全部封装在 events.py 中方法返回的场次event.get_race()正赛event.get_qualifying()排位赛event.get_sprint()/event.get_sprint_shootout()/event.get_sprint_qualifying()冲刺赛相关场次视年份赛制而定event.get_practice(1/2/3)指定的练习赛从 Event.get_session 的实现 可以看出这些便捷方法最终都会落到get_session(identifier)并以当前 Event 的信息构造出对应的Session对象。按名称加载模糊匹配机制与使用注意事项除分站序号外你也可以用具有明确辨识度的名称来加载赛事 event fastf1.get_event(2021, French Grand Prix) event[EventName] French Grand Prix支持部分匹配但并非总是精确你并不需要提供完全准确的赛事名称——FastF1 会返回与所给名称最匹配的赛事即使拼写不完整命中正确赛事的概率也很高 event fastf1.get_event(2021, Spain) event[EventName] Spanish Grand Prix但请注意这并不总是有效有时候另一个名字会与你的输入匹配得更好。例如我们想要的其实是Emilia Romagna Grand Prix但由于输入不够完整/准确FastF1 返回了Belgian Grand Prix——原因很简单FastF1 并不是一个智能搜索引擎它只是做字符串的近似匹配。所以务必检查返回结果 event fastf1.get_event(2021, Emilian) event[EventName] Belgian Grand Prix # 匹配到了错误的赛事只要再精确一点就能得到正确结果 event fastf1.get_event(2021, Emilia Romagna) event[EventName] Emilia Romagna Grand Prix按国家或赛道地点加载赛事还可以用国家名或赛道所在城市/地区加载 session fastf1.get_session(2021, Silverstone, Q) session.event[EventName] British Grand Prix模糊匹配的底层实现这一机制的源码位于 EventSchedule._fuzzy_event_search。要点如下匹配时会综合Location地点、Country国家、EventName赛事名、OfficialEventName官方全名四个字段作为参考字符串匹配前会先剔除常见词汇formula 1、grand prix、gp以及年份字符串剔除常见词后剩余部分长度小于 4 个字符会直接抛出ValueError这就是为什么gp、f1这类输入不可用底层使用模糊匹配器见 fastf1/internals/fuzzy.py并设置绝对置信度阈值 0.5、相对置信度阈值 0.1若匹配结果并非完全精确日志会输出Correcting user input ... to ...提示你输入被纠正成了什么。开启精确匹配如果你希望严格精确匹配可以给get_event/get_session传入exact_matchTrue实现见 events.py。此时必须提供与EventName完全一致的名称忽略大小写否则抛出KeyError event fastf1.get_event(2021, British Grand Prix, exact_matchTrue) # 正常 event fastf1.get_event(2021, British, exact_matchTrue) # 抛 KeyError官方文档还给出了一条实用建议输入名称时应尽量避免常见词例如用Belgium而不是Belgian Grand Prix以降低误匹配概率。赛事日程EventSchedule一整年的大名单与其加载单个赛事或场次你也可以加载整个赛季的完整赛程。EventSchedule是pandas.DataFrame的子类源码定义 schedule fastf1.get_event_schedule(2021) schedule RoundNumber Country ... Session5DateUtc F1ApiSupport 0 0 Bahrain ... NaT False 1 1 Bahrain ... 2021-03-28 15:00:00 True 2 2 Italy ... 2021-04-18 13:00:00 True 3 3 Portugal ... 2021-05-02 14:00:00 True 4 4 Spain ... 2021-05-09 13:00:00 True 5 5 Monaco ... 2021-05-23 13:00:00 True 6 6 Azerbaijan ... 2021-06-06 12:00:00 True 7 7 France ... 2021-06-20 13:00:00 True 8 8 Austria ... 2021-06-27 13:00:00 True 9 9 Austria ... 2021-07-04 13:00:00 True 10 10 Great Britain ... 2021-07-18 14:00:00 True 11 11 Hungary ... 2021-08-01 13:00:00 True 12 12 Belgium ... 2021-08-29 13:00:00 True 13 13 Netherlands ... 2021-09-05 13:00:00 True 14 14 Italy ... 2021-09-12 13:00:00 True 15 15 Russia ... 2021-09-26 12:00:00 True 16 16 Turkey ... 2021-10-10 12:00:00 True 17 17 United States ... 2021-10-24 19:00:00 True 18 18 Mexico ... 2021-11-07 19:00:00 True 19 19 Brazil ... 2021-11-14 17:00:00 True 20 20 Qatar ... 2021-11-21 14:00:00 True 21 21 Saudi Arabia ... 2021-12-05 17:30:00 True 22 22 Abu Dhabi ... 2021-12-12 13:00:00 True [23 rows x 23 columns]日程表共23 列列名如下与Event的字段一一对应 schedule.columns Index([RoundNumber, Country, Location, OfficialEventName, EventDate, EventName, EventFormat, Session1, Session1Date, Session1DateUtc, Session2, Session2Date, Session2DateUtc, Session3, Session3Date, Session3DateUtc, Session4, Session4Date, Session4DateUtc, Session5, Session5Date, Session5DateUtc, F1ApiSupport], dtypeobject)注意上表第 0 行RoundNumber0、Session5DateUtcNaT、F1ApiSupportFalse的巴林记录是季前测试赛EventFormattesting。2021 年 23 行数据 1 次测试赛 22 场大奖赛。从日程表中挑选特定赛事EventSchedule提供了两个内置选择方法源码 gp_12 schedule.get_event_by_round(12) gp_12[Country] Belgium gp_austin schedule.get_event_by_name(Austin) gp_austin[Country] United Statesget_event_by_round(round_number)按分站序号取序号不存在会抛ValueError测试赛的 round 为 0无法用此方法获取get_event_by_name(name, exact_matchFalse)名称匹配逻辑与上文模糊匹配完全一致。日程表的数据来源backend 参数get_event_schedule还接受一个backend参数控制数据来源源码逻辑见 events.pybackend说明支持范围fastf1FastF1 官方后端功能最完整2018 年至今f1timing基于 F1 live timing API无计时数据的场次不会列出2018 年至今ergast基于 Ergast 数据库无本地时间、无计时数据可用性信息1950 年至今不指定backend时默认优先使用fastf1失败后依次回退到f1timing、ergast若年份早于 2018则直接使用ergast。该回退机制体现在 get_event_schedule 的调用链 中。此外get_event_schedule(year, include_testingFalse)可排除测试赛配套函数get_events_remaining()则返回赛季剩余赛事。关于日程表每一列的详细说明可参见 docs/api_reference/events.rst 中的 event-schedule 章节。加载赛果Session.load与session.results到目前为止我们创建的 Session 还什么都没做是时候让它变得有趣了查看一场排位赛的赛果。前提是调用Session.load它会从各个 API 拉取该场次所有可用的数据 session fastf1.get_session(2021, French Grand Prix, Q) session.load() session.results DriverNumber BroadcastName Abbreviation ... Status Points Laps 33 33 M VERSTAPPEN VER ... NaN NaN 44 44 L HAMILTON HAM ... NaN NaN 77 77 V BOTTAS BOT ... NaN NaN 11 11 S PEREZ PER ... NaN NaN 55 55 C SAINZ SAI ... NaN NaN 10 10 P GASLY GAS ... NaN NaN 16 16 C LECLERC LEC ... NaN NaN 4 4 L NORRIS NOR ... NaN NaN 14 14 F ALONSO ALO ... NaN NaN 3 3 D RICCIARDO RIC ... NaN NaN 31 31 E OCON OCO ... NaN NaN 5 5 S VETTEL VET ... NaN NaN 99 99 A GIOVINAZZI GIO ... NaN NaN 63 63 G RUSSELL RUS ... NaN NaN 47 47 M SCHUMACHER MSC ... NaN NaN 6 6 N LATIFI LAT ... NaN NaN 7 7 K RAIKKONEN RAI ... NaN NaN 9 9 N MAZEPIN MAZ ... NaN NaN 18 18 L STROLL STR ... NaN NaN 22 22 Y TSUNODA TSU ... NaN NaN [20 rows x 22 columns]数据下载与处理通常需要几秒钟。强烈建议启用 FastF1 内置的缓存功能来加速重复加载并避免过多的 API 请求具体用法参见 docs/api_reference/cache_and_rate_limits.rst。Session.load的参数与加载内容load 方法签名 如下session.load(*, lapsTrue, telemetryTrue, weatherTrue, messagesTrue, livedataNone)lapsTrue加载圈速数据、赛道状态、场次状态等telemetryTrue加载遥测数据速度、转速、油门等weatherTrue加载天气数据messagesTrue加载赛事播报Race Control消息livedata可传入本地保存的 live timing 数据作为数据源替代 API 请求。默认会加载全部数据。官方文档建议保持全量加载因为 FastF1 内部会混合多个数据端点来纠错和补充信息部分数据不可用时它会尽力降级返回。加载完成后Session还暴露了一大批只读属性定义见 core.pydrivers参赛车手列表、laps、results、weather_data、car_data、pos_data、session_status、track_status、race_control_messages、session_start_time等。若你在未调用load()前访问这些属性会抛出DataNotLoadedError实现见 _get_property_warn_not_loaded提醒你先加载数据。SessionResults赛果数据对象session.results返回的是fastf1.core.SessionResults同样是pandas.DataFrame的子类类定义。它的22 列如下 session.results.columns Index([DriverNumber, BroadcastName, Abbreviation, DriverId, TeamName, TeamColor, TeamId, FirstName, LastName, FullName, HeadshotUrl, CountryCode, Position, ClassifiedPosition, GridPosition, Q1, Q2, Q3, Time, Status, Points, Laps], dtypeobject)其中值得重点说明的列详细语义见 core.py 中的列文档DriverNumber/Abbreviation/BroadcastName/FullName车手编号、三字母缩写、播报名、全名TeamName/TeamColor/TeamId车队名无冠名赞助商、车队代表色十六进制值、车队 IDPosition最终名次会考虑赛后处罚与取消资格而ClassifiedPosition是官方分级结果可能是整数或R退赛/D取消资格/E除名/W退出/F未晋级/N未分级Q1/Q2/Q3排位赛三节的最快圈仅排位类场次有值类型为pd.TimedeltaGridPosition发车位置仅正赛/冲刺类场次有值Time正赛类为总用时练习类为最快圈Status完赛状态如Finished、 1 Lap、Crash、Gearbox等。需要注意所有列始终存在即使对当前场次没有意义如排位赛中GridPosition、Points为NaN。实战示例显示前十名车手及其 Q3 时间赛果按完赛名次排序因此取前 10 名非常直接 session.results.iloc[0:10].loc[:, [Abbreviation, Q3]] Abbreviation Q3 33 VER 0 days 00:01:29.990000 44 HAM 0 days 00:01:30.248000 77 BOT 0 days 00:01:30.376000 11 PER 0 days 00:01:30.445000 55 SAI 0 days 00:01:30.840000 10 GAS 0 days 00:01:30.868000 16 LEC 0 days 00:01:30.987000 4 NOR 0 days 00:01:31.252000 14 ALO 0 days 00:01:31.340000 3 RIC 0 days 00:01:31.382000圈速以Timedelta表示恰好能体现 Pandas 数据模型的便利——直接做数值比较与排序即可无需手动解析时间字符串。圈速数据Laps所有车手的每一个单圈Session.laps属性返回fastf1.core.Laps对象pandas.DataFrame的子类类定义见 core.py包含该场次所有车手跑出的全部单圈 session fastf1.get_session(2021, French Grand Prix, Q) session.load() session.laps Time Driver ... FastF1Generated IsAccurate 0 0 days 00:17:35.479000 GAS ... False False 1 0 days 00:27:42.702000 GAS ... False False 2 0 days 00:30:15.038000 GAS ... False False 3 0 days 00:31:46.936000 GAS ... False True 4 0 days 00:34:20.695000 GAS ... False False .. ... ... ... ... ... 265 0 days 00:54:22.881000 GIO ... False True 266 0 days 01:00:32.369000 GIO ... False False 267 0 days 01:03:24.940000 GIO ... False False 268 0 days 01:04:56.753000 GIO ... False True 269 0 days 01:06:42.885000 GIO ... False False [270 rows x 31 columns]一场排位赛就有超过 250 圈、31 列信息。可用列如下 session.laps.columns Index([Time, Driver, DriverNumber, LapTime, LapNumber, Stint, PitOutTime, PitInTime, Sector1Time, Sector2Time, Sector3Time, Sector1SessionTime, Sector2SessionTime, Sector3SessionTime, SpeedI1, SpeedI2, SpeedFL, SpeedST, IsPersonalBest, Compound, TyreLife, FreshTyre, Team, LapStartTime, LapStartDate, TrackStatus, Position, Deleted, DeletedReason, FastF1Generated, IsAccurate], dtypeobject)所有列的详细解释可在Laps类的 API 文档中找到对应 docs/api_reference/timing_data.rst 等章节。这里先给出几个高频字段的快速参考Time/LapStartTime该圈被记录的时刻 / 该圈开始时刻TimedeltaLapTime圈速用时Sector1Time/Sector2Time/Sector3Time三段计时LapNumber圈号Stint进站前的stint序号Compound/TyreLife/FreshTyre轮胎配方SOFT/MEDIUM/HARD/INTERMEDIATE/WET 等、轮胎使用圈数、是否新胎IsPersonalBest是否为该车手全场最快圈个人最快Deleted/DeletedReason该圈是否因违规如超出赛道限制被删除FastF1Generated/IsAccurate标记 FastF1 补生成的圈如事故/退赛场景与数据准确性SpeedI1/SpeedI2/SpeedFL/SpeedST三个速度陷阱点与直道尾速。Laps的专属选择方法Laps并非简单的 DataFrame——和 FastF1 的其他数据对象一样它提供了专门面向 F1 数据的增强方法源码见 core.py。其中出场率最高的是pick_fastest() fastest_lap session.laps.pick_fastest() fastest_lap[LapTime] Timedelta(0 days 00:01:29.990000) fastest_lap[Driver] VERpick_fastest的默认行为实现见 core.py值得展开说明默认只考虑IsPersonalBest True的圈。如果按LapTime最快的圈并非个人最快例如因超出赛道限制被删除成绩该圈不会被选中——这正是排位赛场景下最快圈与杆位圈需要区分的细节如果没有任何圈被标记为个人最快或self中没有圈则返回None传入only_by_timeTrue可以关闭个人最快校验直接返回LapTime最小的那一圈若出现多个同时间的圈取第一个被记录到的。此外常用的还有# 107% 规则返回比全场最快圈慢不超过 threshold 倍的所有圈 quick_laps session.laps.pick_quicklaps() # 默认 1.07 quick_laps session.laps.pick_quicklaps(threshold1.05) # 自定义 105% # 按轮胎配方筛选 soft_laps session.laps.pick_compounds(SOFT) slick_laps session.laps.pick_compounds([SOFT, MEDIUM, HARD])pick_quicklaps默认阈值来自Laps.QUICKLAP_THRESHOLD107%pick_compounds则接受单个字符串或字符串列表core.py 实现。圈速数据的可视化延伸官方仓库提供了大量基于这些数据的绘图示例。与本文最贴合的当属 examples/results_strategy/plot_qualifying_results.py——它正是从session.laps.pick_fastest()出发将各车手的最快圈速绘制成排位赛成绩对比图是理解本指南全部内容的完美实战收尾。更多示例见 examples 目录涵盖圈速分布、策略分析、遥测对比等主题。小结一次完整的入门工作流将本文内容串成一段可运行的完整流程import fastf1 # 1. 加载场次名称模糊匹配 会话缩写 session fastf1.get_session(2021, French Grand Prix, Q) # 2. 查看赛事信息Event 是 pandas.Series print(session.event[EventName], session.event[Country]) # 3. 加载全部场次数据建议配合 FastF1 缓存 session.load() # 4. 查看赛果与圈速 print(session.results[[Abbreviation, Q3]].head(10)) pole session.laps.pick_fastest() print(pole[Driver], pole[LapTime]) # 5. 加载整年赛程并定位特定赛事 schedule fastf1.get_event_schedule(2021) print(schedule.get_event_by_round(12)[Country])核心要点回顾对象体系FastF1 的一切数据都以 PandasDataFrame/Series子类呈现Event、EventSchedule、SessionResults、Laps可无缝使用 Pandas API加载三兄弟get_session(year, gp, identifier)、get_event(year, gp)、get_event_schedule(year)其中gp支持序号与名称含模糊匹配identifier支持缩写/名称/序号名称匹配有风险模糊匹配不是智能搜索务必核对返回的EventName必要时用exact_matchTrue先 load 再取数get_session只返回空壳对象所有场次数据都要在session.load()之后才能访问否则会抛DataNotLoadedError记住 F1 特有列Q1/Q2/Q3、Compound、IsPersonalBest、Deleted、FastF1Generated等列承载着赛车运动特有的语义选圈、筛选时务必理解其含义。掌握了这些基础你就可以在此基础上继续深入 docs/getting_started/installation.rst 完成环境安装并进阶学习遥测数据、圈速可视化与策略分析等更高阶主题。【免费下载链接】Fast-F1FastF1 is a python package for accessing and analyzing Formula 1 results, schedules, timing data and telemetry项目地址: https://gitcode.com/GitHub_Trending/fa/Fast-F1创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考