如何按UpdateTime分组计算每行与组内Rank1行的差值?[Python]
按UpdateTime分组计算每行与rank=1行的差值优化
数据集样例
data = {'CarNo': [888, 81, 16, 62, 31, 23, 777, 23, 777, 31, 888, 62, 81, 16, 888, 31, 81, 62, 16, 23], 'LapTime': [119628, 117170, 119846, 117178, 119516, 117915, 116964, 116683, 117169, 118919, 119227, 117789, 117674, 116914, 116333, 120027, 116403, 117351, 116557, 117107], 'LAPS': [147.0, 147.0, 147.0, 147.0, 147.0, 146.0, 121.0, 56.0, 55.0, 55.0, 55.0, 54.0, 54.0, 54.0, 123.0, 123.0, 123.0, 123.0, 123.0, 122.0], 'UpdateTime': [162047732, 162047732, 162047732, 162047732, 162047732, 162047732, 162047732, 125626988, 125626988, 125626988, 125626988, 125626988, 125626988, 125626988, 151851068, 151851068, 151851068, 151851068, 151851068, 151851068], 'rank': [6.0, 2.0, 7.0, 3.0, 5.0, 4.0, 1.0, 1.0, 3.0, 6.0, 7.0, 5.0, 4.0, 2.0, 1.0, 7.0, 2.0, 5.0, 3.0, 4.0] } df = pd.DataFrame(data)
需求
按UpdateTime字段分组,计算每组内每行的LapTime与组内rank=1行的LapTime的差值。
原代码问题
你之前的代码存在两个核心问题:
- 使用
iloc[1:]会跳过每组的首行(即rank=1的行),导致这些行的差值丢失(本该为0); - 手动处理索引位置的方式未利用Pandas原生分组能力,逻辑冗余且效率低下。
原代码:
def diff_to_top(df,colA): pos=sub.columns.get_loc(colA) gap = sub.iloc[1:, pos] - sub.iat[0, pos] return gap sub = df.set_index(['UpdateTime','rank','LAPS']) sub.sort_index(inplace=True, ascending=True) diff_to_top(sub,'LapTime')
优化方案
方案1:使用groupby+transform(简洁高效)
直接利用Pandas分组转换功能,对每组提取rank=1的LapTime作为基准,批量计算差值:
# 新增列存储与rank=1行的差值 df['LapTime_diff_to_top'] = df.groupby('UpdateTime')['LapTime'].transform( lambda group: group - group[df.loc[group.index, 'rank'] == 1].iloc[0] )
方案2:先提取基准再合并(大数据集更高效)
先单独提取每组rank=1的LapTime,再合并到原数据集计算差值,避免lambda循环,适合大数据量场景:
# 提取每组rank=1的LapTime作为基准值 top_laptime = df[df['rank'] == 1].groupby('UpdateTime')['LapTime'].first().reset_index(name='TopLapTime') # 合并基准值到原数据集 df = df.merge(top_laptime, on='UpdateTime', how='left') # 计算差值 df['LapTime_diff_to_top'] = df['LapTime'] - df['TopLapTime']
两种方案都能保留所有行的数据,且完全利用Pandas向量运算特性,效率远高于手动处理索引的方式。
内容的提问来源于stack exchange,提问作者アルサ
相关产品推荐
相关产品推荐

