如何为含NaN的马拉松分段成绩每行计算最佳拟合线以填充缺失值
解决思路与实现方案
你的需求本质是利用单选手的有效分段成绩与对应距离的线性关系补全缺失值,核心逻辑基于马拉松选手配速基本稳定、累计用时与跑步距离呈线性相关的普遍规律。
前置准备
首先定义所有行通用的分段距离映射,5个目标列对应的实际跑过的距离(单位:km)如下:
- 对应列名:
['5K', '10K', '15K', '20K', 'Half'] - 对应距离:
[5, 10, 15, 20, 21.0975]
逐行拟合补全步骤
对每一条含缺失值的记录执行以下操作:
- 提取当前行的5项分段成绩,筛选出非NaN的有效成绩,以及这些有效成绩对应的分段距离
- 用有效<距离, 用时>对做一元线性回归,得到拟合线的
斜率与截距 - 对缺失值所在的分段,代入对应距离到拟合公式
用时 = 斜率 * 距离 + 截距,计算得到的预测值替换原NaN
注意:如果某行有效成绩点少于2个无法进行线性回归,你可以根据需求选择保留原NaN、用同年龄/性别组的同分段平均成绩补全,或者直接剔除该行。
Python 实现代码
基于pandas和numpy的可直接运行参考代码:
import pandas as pd import numpy as np # 配置参数:分段列名与对应距离 SEGMENT_COLS = ['5K', '10K', '15K', '20K', 'Half'] SEGMENT_DIST = np.array([5, 10, 15, 20, 21.0975]) def fill_missing_segment(row): # 提取当前行的分段成绩数组 scores = row[SEGMENT_COLS].values # 筛选有效数据的掩码 valid_mask = ~np.isnan(scores) valid_scores = scores[valid_mask] # 有效点不足2个直接返回原行,可自行修改为其他补全逻辑 if len(valid_scores) < 2: return row # 提取有效数据对应的x(距离)和y(用时) valid_x = SEGMENT_DIST[valid_mask] # 计算一元线性拟合参数,返回[斜率, 截距] slope, intercept = np.polyfit(valid_x, valid_scores, deg=1) # 填充缺失值 nan_mask = np.isnan(scores) scores[nan_mask] = slope * SEGMENT_DIST[nan_mask] + intercept # 写回处理后的成绩 row[SEGMENT_COLS] = scores return row # 对整个数据集应用处理逻辑,df为你加载的原始数据集 df_filled = df.apply(fill_missing_segment, axis=1)
样例验证结果
对你给出的第2327行样本,有效数据为10K到半马的4个成绩,拟合得到斜率约为252.8、截距约为-10.5,代入5K的距离计算得到预测值约为1253.5,和同成绩段其他选手的5K成绩范围一致,符合预期。
内容的提问来源于stack exchange,提问作者user15936471
相关产品推荐
相关产品推荐

