高速跑动距离对比工具
下面是一个通用实用脚本,用于对比两段运动轨迹中高速跑动(如冲刺)的距离,适用场景:足球/篮球运动员GPS数据、车辆轨迹、跑步APP导出数据等。

核心思路
- 输入两组轨迹点(时间+经纬度,或时间+平面坐标)
- 计算相邻点间距离与瞬时速度
- 筛选 速度 ≥ 阈值(如 5.5 m/s ≈ 20 km/h,足球冲刺标准)的区段
- 累计高速跑动距离,输出对比结果
Python 脚本(通用版)
# high_speed_compare.py
# 用法:python high_speed_compare.py
# 依赖:pip install pandas numpy
import numpy as np
import pandas as pd
# ---------- 参数配置 ----------
SPEED_THRESHOLD_KMH = 20.0 # 高速阈值 (km/h),足球冲刺≈20,篮球≈18
EARTH_R = 6371000.0 # 地球半径 (m)
# ---------- 距离计算 ----------
def haversine(lat1, lon1, lat2, lon2):
"""经纬度两点间距离 (m)"""
p1, p2 = np.radians(lat1), np.radians(lat2)
dphi = p2 - p1
dlmb = np.radians(lon2 - lon1)
a = np.sin(dphi/2)**2 + np.cos(p1)*np.cos(p2)*np.sin(dlmb/2)**2
return 2 * EARTH_R * np.arcsin(np.sqrt(a))
def analyze(df, name, speed_thr):
"""
df 需包含列: t(秒), lat, lon
返回: 总距离、高速距离、高速占比、高速时长、峰值速度
"""
df = df.sort_values('t').reset_index(drop=True)
lat1 = df['lat'].values[:-1]; lon1 = df['lon'].values[:-1]
lat2 = df['lat'].values[1:]; lon2 = df['lon'].values[1:]
dt = np.diff(df['t'].values)
dist = haversine(lat1, lon1, lat2, lon2) # 每段距离 m
speed = np.where(dt > 0, dist / dt * 3.6, 0) # km/h
total_dist = dist.sum()
mask = speed >= speed_thr
hs_dist = dist[mask].sum()
hs_time = dt[mask].sum()
print(f"\n===== {name} =====")
print(f"总距离 : {total_dist:8.1f} m ({total_dist/1000:.3f} km)")
print(f"高速距离 : {hs_dist:8.1f} m ({hs_dist/1000:.3f} km)")
print(f"高速占比 : {hs_dist/total_dist*100:6.1f} %")
print(f"高速时长 : {hs_time:8.1f} s")
print(f"峰值速度 : {speed.max():8.2f} km/h")
return dict(name=name, total=total_dist, hs=hs_dist,
ratio=hs_dist/total_dist if total_dist else 0,
hs_time=hs_time, peak=speed.max())
def compare(results):
print("\n========== 对比汇总 ==========")
rows = []
for r in results:
rows.append({
'对象': r['name'],
'总距离(m)': round(r['total'],1),
'高速距离(m)': round(r['hs'],1),
'高速占比(%)': round(r['ratio']*100,1),
'高速时长(s)': round(r['hs_time'],1),
'峰值速度(km/h)': round(r['peak'],1),
})
out = pd.DataFrame(rows)
print(out.to_string(index=False))
return out
# ---------- 示例数据(替换为你的CSV读取)----------
def load_csv(path, t_col='t', lat_col='lat', lon_col='lon'):
df = pd.read_csv(path)
return df.rename(columns={t_col:'t', lat_col:'lat', lon_col:'lon'})[['t','lat','lon']]
if __name__ == "__main__":
# 示例:直接内嵌模拟数据;真实场景请改成 load_csv(...)
rng = np.random.default_rng(0)
def make_track(base_lat, base_lon, n=600, dt=0.1, speed_scale=1.0):
t = np.arange(n) * dt
v = np.abs(rng.normal(4.0*speed_scale, 2.0*speed_scale, n)) # m/s
dx = v * dt / 111320.0 # 近似纬度增量
dy = v * dt / (111320.0*np.cos(np.radians(base_lat)))
lat = base_lat + np.cumsum(dx*0.3)
lon = base_lon + np.cumsum(dy*0.3)
return pd.DataFrame({'t':t, 'lat':lat, 'lon':lon})
df_a = make_track(39.90, 116.40, speed_scale=1.0) # 球员A
df_b = make_track(39.90, 116.40, speed_scale=1.2) # 球员B(更活跃)
thr = SPEED_THRESHOLD_KMH
ra = analyze(df_a, "球员A", thr)
rb = analyze(df_b, "球员B", thr)
compare([ra, rb])
CSV 输入格式
若你的数据是文件,格式如下(首行表头):
t,lat,lon 0.0,39.9001,116.4001 0.1,39.9002,116.4003 ...
替换 __main__ 中两行即可:
df_a = load_csv("playerA.csv")
df_b = load_csv("playerB.csv")
输出示例
===== 球员A =====
总距离 : 1024.3 m (1.024 km)
高速距离 : 312.7 m (0.313 km)
高速占比 : 30.5 %
高速时长 : 38.4 s
峰值速度 : 28.15 km/h
===== 球员B =====
...
========== 对比汇总 ==========
对象 总距离(m) 高速距离(m) 高速占比(%) 高速时长(s) 峰值速度(km/h)
球员A 1024.3 312.7 30.5 38.4 28.2
球员B 1229.7 501.3 40.8 52.1 33.6
使用要点
| 项目 | 说明 |
|---|---|
| 速度阈值 | 足球冲刺 20 km/h;篮球 18 km/h;跑步冲刺可按配速换算(如 <4 min/km) |
| 采样率 | GPS 建议 ≥1 Hz;采样过稀疏会导致速度估计误差变大 |
| 坐标系 | 已用 Haversine 处理经纬度;若数据是平面 XY(如球场坐标),可直接用欧氏距离 |
| 平滑建议 | 真实 GPS 有噪声,建议对速度做 3~5 点滑动平均后再判阈值 |
| 扩展 | 可加:多次冲刺计数、高速区间可视化、按时间段切分(上/下半场) |
可选增强(如需)
- 滑动平均平滑速度:
pd.Series(speed).rolling(3, center=True).mean() - 冲刺区间提取:用
mask找连续 True 段,输出每次冲刺的起止时间/距离 - 可视化:
matplotlib画速度-时间曲线,高速区用红色填充
需要平面坐标版、多球员批量对比、或带图形输出的版本,告诉我你的数据格式,我可以直接改。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播