慢跑恢复时间数据统计脚本
我无法访问你的具体数据,但可以给你一套可直接运行的脚本框架,涵盖常见统计需求,你可以根据自己的数据格式调整。

假设的数据格式
CSV 文件(running_data.csv)示例:
date,distance_km,duration_min,avg_hr,rest_hr,recovery_min,feeling 2024-05-01,5.0,32,145,58,45,good 2024-05-03,6.2,41,150,60,60,normal 2024-05-05,4.5,28,138,57,30,good 2024-05-08,8.0,55,155,62,90,tired 2024-05-10,5.5,35,142,59,50,good
完整 Python 脚本
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文显示
plt.rcParams['axes.unicode_minus'] = False
# ---------- 1. 读取数据 ----------
df = pd.read_csv('running_data.csv', parse_dates=['date'])
df = df.sort_values('date').reset_index(drop=True)
# 计算配速 (min/km) 和恢复率
df['pace_min_per_km'] = df['duration_min'] / df['distance_km']
df['recovery_per_km'] = df['recovery_min'] / df['distance_km']
# ---------- 2. 基础统计 ----------
print("=" * 50)
print("【恢复时间基础统计】")
print(df['recovery_min'].describe().round(1))
print("\n【按主观感受分组的恢复时间】")
print(df.groupby('feeling')['recovery_min']
.agg(['count', 'mean', 'median', 'std']).round(1))
print("\n【恢复时间与各指标相关性】")
corr_cols = ['distance_km', 'duration_min', 'avg_hr', 'pace_min_per_km', 'recovery_min']
print(df[corr_cols].corr()['recovery_min'].round(3))
# ---------- 3. 趋势分析(线性回归) ----------
x = np.arange(len(df))
slope, intercept, r, p, se = stats.linregress(x, df['recovery_min'])
print(f"\n【恢复时间趋势】斜率={slope:.2f} min/次, R²={r**2:.3f}, p={p:.3f}")
print("→ 恢复时间" + ("呈下降趋势 ✅ 体能改善" if slope < 0 else "呈上升趋势 ⚠️ 注意疲劳积累"))
# ---------- 4. 异常检测(Z-score) ----------
df['z'] = np.abs(stats.zscore(df['recovery_min']))
outliers = df[df['z'] > 2]
print(f"\n【异常恢复日】(Z>2): {len(outliers)} 次")
if not outliers.empty:
print(outliers[['date', 'recovery_min', 'feeling']].to_string(index=False))
# ---------- 5. 可视化 ----------
fig, axes = plt.subplots(2, 2, figsize=(13, 9))
# 5.1 恢复时间趋势
axes[0, 0].plot(df['date'], df['recovery_min'], 'o-', color='#1f77b4')
axes[0, 0].plot(df['date'], intercept + slope * x, '--', color='red', label=f'趋势 {slope:+.2f}/次')
axes[0, 0].set_title('恢复时间趋势')
axes[0, 0].set_ylabel('恢复时间 (min)')
axes[0, 0].legend(); axes[0, 0].grid(alpha=0.3)
# 5.2 距离 vs 恢复时间
axes[0, 1].scatter(df['distance_km'], df['recovery_min'], c='#2ca02c', s=60)
axes[0, 1].set_xlabel('距离 (km)'); axes[0, 1].set_ylabel('恢复时间 (min)')
axes[0, 1].set_title('距离 vs 恢复时间'); axes[0, 1].grid(alpha=0.3)
# 5.3 心率 vs 恢复时间
axes[1, 0].scatter(df['avg_hr'], df['recovery_min'], c='#d62728', s=60)
axes[1, 0].set_xlabel('平均心率'); axes[1, 0].set_ylabel('恢复时间 (min)')
axes[1, 0].set_title('心率 vs 恢复时间'); axes[1, 0].grid(alpha=0.3)
# 5.4 按感受分组箱线图
df.boxplot(column='recovery_min', by='feeling', ax=axes[1, 1])
axes[1, 1].set_title('不同感受下的恢复时间')
axes[1, 1].set_xlabel('主观感受'); axes[1, 1].set_ylabel('恢复时间 (min)')
plt.suptitle('')
plt.tight_layout()
plt.savefig('recovery_analysis.png', dpi=150)
plt.show()
# ---------- 6. 导出汇总 ----------
summary = {
'总训练次数': len(df),
'平均恢复时间(min)': round(df['recovery_min'].mean(), 1),
'中位数恢复时间(min)': round(df['recovery_min'].median(), 1),
'最长恢复(min)': df['recovery_min'].max(),
'最短恢复(min)': df['recovery_min'].min(),
'恢复时间标准差': round(df['recovery_min'].std(), 1),
'趋势斜率(min/次)': round(slope, 2),
'异常日数量': len(outliers),
}
pd.Series(summary).to_csv('recovery_summary.csv', header=['value'])
print("\n✅ 已保存图表 recovery_analysis.png 和汇总 recovery_summary.csv")
脚本输出内容解读
| 模块 | 作用 | 关键指标 |
|---|---|---|
| 基础统计 | 了解整体水平 | 均值/中位数/标准差 |
| 分组统计 | 按感受分组 | 不同疲劳度下的恢复差异 |
| 相关性 | 找影响因素 | 距离/心率/配速与恢复的关系 |
| 趋势回归 | 看体能变化 | 斜率为负 = 进步 |
| 异常检测 | 找异常日 | Z-score > 2 的日子 |
| 可视化 | 直观呈现 | 趋势图+散点+箱线图 |
需要你确认的几点
- 数据文件路径:脚本默认读
running_data.csv,请替换为你的实际文件。 - 字段名:如果你的列名不同(如
rest_time、恢复时间),改脚本里的字段名即可。 - 恢复时间定义:你指的是「跑后到静息心率恢复的时间」还是「主观感受的疲劳消退时间」?前者建议同时记录跑后即刻心率和恢复到静息所需分钟,可加入
hr_drop_rate = (跑后HR - 静息HR) / recovery_min这一指标,更能反映心肺恢复能力。 - 是否有多人数据:如果是多人,需要加
groupby('runner_id')分组统计。
如果你把实际 CSV 的前几行(或字段名)发给我,我可以帮你改好脚本直接跑,你也可以告诉我你最关心的指标(每周平均恢复时间变化」或「配速对恢复的影响」),我帮你补充对应分析。
友情链接
版权声明:本站文章为原创整理,转载请注明出处。