如何基于F1赛事数据在Pandas中生成车手组合新DataFrame?
问题
我有一个记录不同F1车手赛事情况的大型Pandas DataFrame,以Racer_Number为索引,数据结构如下:
Racer_Number Meeting_Number Date Runners a b 1 1 29/11/2015 4 0.002 0.004 2 1 29/11/2015 4 0.088 0.058 3 1 29/11/2015 4 0.215 0.177 4 1 29/11/2015 4 0.215 0.194 1 2 29/11/2015 3 0.025 0.019 2 2 29/11/2015 3 0.364 0.388 3 2 29/11/2015 3 0.024 0.041 1 3 29/11/2015 5 0.001 0.003 2 3 29/11/2015 5 0.004 0.005 3 3 29/11/2015 5 0.002 0.003 4 3 29/11/2015 5 0.010 0.011 5 3 29/11/2015 5 0.051 0.096
需要生成新DataFrame,要求:
- 每行是同一赛事(相同
Meeting_Number)下车手的两两组合,格式为i_j(i<j,避免重复) - 新增
aa列:组合中车手i的a值与车手j的a值的乘积 - 新增
ab列:组合中车手i的a值与车手j的b值的乘积
期望输出如下:
Racer_Combination Meeting_Number Date Runners aa ab 1_2 1 29/11/2015 4 0.000191 0.000127 1_3 1 29/11/2015 4 0.000468 0.000386 1_4 1 29/11/2015 4 0.000468 0.000423 2_3 1 29/11/2015 4 0.018793 0.015513 2_4 1 29/11/2015 4 0.018802 0.016991 3_4 1 29/11/2015 4 0.046069 0.041631 1_2 2 29/11/2015 3 0.009241 0.009839 1_3 2 29/11/2015 3 0.000599 0.001033 2_3 2 29/11/2015 3 0.008605 0.014848 1_2 3 29/11/2015 5 0.000004 0.000006 1_3 3 29/11/2015 5 0.000002 0.000004 1_4 3 29/11/2015 5 0.000012 0.000013 1_5 3 29/11/2015 5 0.000062 0.000115 2_3 3 29/11/2015 5 0.000006 0.000013 2_4 3 29/11/2015 5 0.000036 0.000041 2_5 3 29/11/2015 5 0.000191 0.000355 3_4 3 29/11/2015 5 0.000015 0.000017 3_5 3 29/11/2015 5 0.000079 0.000146 4_5 3 29/11/2015 5 0.000499 0.000931
解决方案
实现代码
import pandas as pd from itertools import combinations # 若原始数据的Racer_Number不是索引,先执行以下语句转换 # df = df.set_index('Racer_Number') def process_race_group(group): # 获取当前赛事的所有车手编号 racers = group.index.tolist() # 生成所有不重复的两两组合(i<j) racer_combos = combinations(racers, 2) result_rows = [] for racer_i, racer_j in racer_combos: # 提取两位车手的a、b值 a_i, b_i = group.loc[racer_i, ['a', 'b']] a_j, b_j = group.loc[racer_j, ['a', 'b']] # 计算目标列值并保留6位小数 aa_val = round(a_i * a_j, 6) ab_val = round(a_i * b_j, 6) # 整理行数据,赛事信息取组内统一值 result_rows.append({ 'Racer_Combination': f"{racer_i}_{racer_j}", 'Meeting_Number': group['Meeting_Number'].iloc[0], 'Date': group['Date'].iloc[0], 'Runners': group['Runners'].iloc[0], 'aa': aa_val, 'ab': ab_val }) return pd.DataFrame(result_rows) # 按赛事分组处理并合并结果 final_df = df.groupby('Meeting_Number').apply(process_race_group).reset_index(drop=True)
代码说明
- 分组拆分:通过
groupby('Meeting_Number')将数据按赛事拆分,确保只在同一赛事内生成车手组合。 - 生成组合:使用
itertools.combinations生成车手的两两不重复组合,避免i_j和j_i的重复计算。 - 计算列值:遍历每个组合,提取对应车手的
a、b值,计算aa和ab并保留6位小数。 - 合并结果:将所有分组的处理结果合并,得到最终目标DataFrame。
内容的提问来源于stack exchange,提问作者Apook
相关产品推荐
相关产品推荐

