如何在Pandas中计算运动员上一场比赛的相对最快时间
解决方案
要完成需求,你需要先计算每一场赛事的最快完赛时间(分母),再结合已获取的运动员上一场完赛时间(分子),最终组合成指定格式的字符串。以下是完整步骤和代码:
步骤说明
- 计算各赛事最快完赛时间:按
Race_ID分组,取每组Finish_time的最小值,作为该赛事的最快成绩。 - 匹配上一场赛事的最快成绩:由于
Race_ID是倒序(1最新,4最老),当前赛事的上一场对应Race_ID + 1,通过映射关联上一场的最快成绩作为分母。 - 获取运动员上一场完赛时间:按运动员分组并按赛事时间升序排序后,用
shift(-1)获取该运动员上一场的完赛时间作为分子。 - 格式化为目标字符串:将分子和分母按要求格式组合,最老赛事(
Race_ID=4)的分子为0,对应列值设为"0"。
完整代码
import pandas as pd import numpy as np # 构建原始DataFrame(不带预期的Relative_time@t-1列) data = [ [1,1,56.1], [1,3,60.2], [1,2,57.1], [1,4,57.2], [2,2,56.2], [2,1,56.3], [2,3,56.4], [2,4,56.5], [3,1,61.2], [3,2,62.1], [3,3,60.4], [3,4,60.0], [4,2,55.0], [4,1,54.0], [4,3,53.0], [4,4,52.0] ] df = pd.DataFrame(data, columns=['Race_ID', 'Athlete_ID', 'Finish_time'], dtype=float) # 1. 计算每个赛事的最快完赛时间 race_fastest = df.groupby('Race_ID')['Finish_time'].min() fastest_dict = race_fastest.to_dict() # 2. 添加上一场赛事ID,并映射对应最快时间作为分母 df['Prev_Race_ID'] = df['Race_ID'] + 1 df['Denominator'] = df['Prev_Race_ID'].map(fastest_dict) # 3. 按运动员和赛事升序排序,获取分子(运动员上一场完赛时间) df.sort_values(by=['Athlete_ID', 'Race_ID'], ascending=[True, True], inplace=True) df['Numerator'] = df.groupby('Athlete_ID')['Finish_time'].shift(-1) df['Numerator'] = df['Numerator'].fillna(0) # 4. 格式化为目标字符串 def format_ratio(num, den): if num == 0: return '0' # 处理数值格式:整数显示整数,小数保留一位 num_str = f"{num:.0f}" if num.is_integer() else f"{num:.1f}" den_str = f"{den:.0f}" if den.is_integer() else f"{den:.1f}" return f"{num_str}/{den_str}" df['Relative_time@t-1'] = df.apply(lambda row: format_ratio(row['Numerator'], row['Denominator']), axis=1) # 恢复原始索引顺序并清理中间列 df.sort_index(inplace=True) df.drop(['Prev_Race_ID', 'Numerator', 'Denominator'], axis=1, inplace=True) print(df)
输出结果
运行代码后会得到你预期的DataFrame,Relative_time@t-1列完全符合要求。
内容的提问来源于stack exchange,提问作者Apook
相关产品推荐
相关产品推荐

