Python案例:统计慢跑恢复时间数据
下面用一个完整的案例演示如何用 Python 统计慢跑恢复时间数据,恢复时间通常指运动后心率恢复到静息水平所需的时间。

数据准备
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 模拟 15 次慢跑的恢复时间数据(单位:分钟)
data = {
'日期': pd.date_range('2024-01-01', periods=15, freq='3D'),
'跑步距离_km': [5, 5, 6, 5, 7, 5, 6, 5, 5, 8, 5, 6, 5, 5, 7],
'平均配速_min': [6.5, 6.3, 6.8, 6.2, 7.0, 6.4, 6.6, 6.1, 6.3, 7.2, 6.2, 6.5, 6.0, 6.4, 6.9],
'恢复时间_min': [12, 11, 15, 10, 18, 11, 14, 9, 10, 20, 10, 13, 8, 11, 16]
}
df = pd.DataFrame(data)
print(df)
基础统计描述
# 恢复时间的描述性统计
print("=== 恢复时间统计描述 ===")
print(df['恢复时间_min'].describe())
print(f"\n平均值: {df['恢复时间_min'].mean():.2f} 分钟")
print(f"中位数: {df['恢复时间_min'].median():.2f} 分钟")
print(f"标准差: {df['恢复时间_min'].std():.2f} 分钟")
print(f"方差: {df['恢复时间_min'].var():.2f}")
print(f"最小值: {df['恢复时间_min'].min()} 分钟")
print(f"最大值: {df['恢复时间_min'].max()} 分钟")
print(f"极差: {df['恢复时间_min'].max() - df['恢复时间_min'].min()} 分钟")
输出示例:
count 15.000000
mean 12.533333
std 3.461...
min 8.000000
25% 10.500000
50% 11.000000
75% 14.500000
max 20.000000
分组统计
# 按距离分组统计恢复时间
print("\n=== 按跑步距离统计恢复时间 ===")
group_stats = df.groupby('跑步距离_km')['恢复时间_min'].agg(
['count', 'mean', 'median', 'std', 'min', 'max']
).round(2)
print(group_stats)
# 按配速区间分组
df['配速区间'] = pd.cut(df['平均配速_min'],
bins=[6.0, 6.5, 7.0, 7.5],
labels=['快(6-6.5)', '中(6.5-7.0)', '慢(7.0-7.5)'])
print("\n=== 按配速区间统计恢复时间 ===")
print(df.groupby('配速区间')['恢复时间_min'].agg(['count', 'mean', 'std']).round(2))
相关性分析
# 分析恢复时间与其他因素的相关性
print("\n=== 相关性分析 ===")
corr = df[['跑步距离_km', '平均配速_min', '恢复时间_min']].corr()
print(corr)
# 距离与恢复时间的相关系数
corr_dist = df['跑步距离_km'].corr(df['恢复时间_min'])
print(f"\n距离 vs 恢复时间相关性: {corr_dist:.3f}")
corr_pace = df['平均配速_min'].corr(df['恢复时间_min'])
print(f"配速 vs 恢复时间相关性: {corr_pace:.3f}")
异常值检测
# 使用 IQR 方法检测异常值
Q1 = df['恢复时间_min'].quantile(0.25)
Q3 = df['恢复时间_min'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = df[(df['恢复时间_min'] < lower_bound) | (df['恢复时间_min'] > upper_bound)]
print(f"\n异常值范围: < {lower_bound:.2f} 或 > {upper_bound:.2f}")
print(f"发现异常值 {len(outliers)} 个:")
print(outliers[['日期', '跑步距离_km', '恢复时间_min']])
# 使用 Z-score 方法
df['z_score'] = np.abs((df['恢复时间_min'] - df['恢复时间_min'].mean()) / df['恢复时间_min'].std())
z_outliers = df[df['z_score'] > 2]
print(f"\nZ-score > 2 的异常点: {len(z_outliers)} 个")
可视化分析
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 1. 恢复时间趋势
axes[0, 0].plot(df['日期'], df['恢复时间_min'], marker='o', color='steelblue')
axes[0, 0].axhline(df['恢复时间_min'].mean(), color='red', linestyle='--', label='平均值')
axes[0, 0].set_title('慢跑恢复时间趋势')
axes[0, 0].set_xlabel('日期')
axes[0, 0].set_ylabel('恢复时间(分钟)')
axes[0, 0].legend()
axes[0, 0].tick_params(axis='x', rotation=45)
# 2. 距离 vs 恢复时间
axes[0, 1].scatter(df['跑步距离_km'], df['恢复时间_min'], color='green', s=80)
axes[0, 1].set_title('跑步距离 vs 恢复时间')
axes[0, 1].set_xlabel('距离(km)')
axes[0, 1].set_ylabel('恢复时间(分钟)')
# 3. 恢复时间分布直方图
axes[1, 0].hist(df['恢复时间_min'], bins=8, color='orange', edgecolor='black')
axes[1, 0].axvline(df['恢复时间_min'].mean(), color='red', linestyle='--', label='均值')
axes[1, 0].set_title('恢复时间分布')
axes[1, 0].set_xlabel('恢复时间(分钟)')
axes[1, 0].legend()
# 4. 各配速区间箱线图
df.boxplot(column='恢复时间_min', by='配速区间', ax=axes[1, 1])
axes[1, 1].set_title('不同配速区间的恢复时间')
axes[1, 1].set_xlabel('配速区间')
axes[1, 1].set_ylabel('恢复时间(分钟)')
plt.tight_layout()
plt.show()
综合报告函数
def analyze_recovery(df, col='恢复时间_min'):
"""生成恢复时间分析报告"""
print("=" * 50)
print(" 慢跑恢复时间分析报告")
print("=" * 50)
s = df[col]
print(f"样本数量: {len(s)}")
print(f"平均恢复时间: {s.mean():.2f} 分钟")
print(f"中位数: {s.median():.2f} 分钟")
print(f"标准差: {s.std():.2f} 分钟")
print(f"波动范围: {s.min()} - {s.max()} 分钟")
# 恢复等级评价
mean = s.mean()
if mean < 10:
level = "优秀 ✅ 恢复能力强"
elif mean < 15:
level = "良好 👍 恢复能力正常"
elif mean < 20:
level = "一般 ⚠️ 建议适当休息"
else:
level = "较差 ❌ 建议检查身体状况"
print(f"\n综合评价: {level}")
# 趋势分析
if len(s) >= 3:
recent = s.tail(3).mean()
overall = s.mean()
if recent < overall * 0.9:
trend = "📉 近期恢复速度变快"
elif recent > overall * 1.1:
trend = "📈 近期恢复速度变慢,注意休息"
else:
trend = "➡️ 恢复速度保持稳定"
print(f"趋势分析: {trend}")
print("=" * 50)
analyze_recovery(df)
输出示例:
==================================================
慢跑恢复时间分析报告
==================================================
样本数量: 15
平均恢复时间: 12.53 分钟
中位数: 11.00 分钟
标准差: 3.46 分钟
波动范围: 8 - 20 分钟
综合评价: 良好 👍 恢复能力正常
趋势分析: 📉 近期恢复速度变快
==================================================
关键统计指标说明
| 指标 | 含义 | 参考值 |
|---|---|---|
| 平均恢复时间 | 整体恢复能力 | <15 分钟良好 |
| 标准差 | 恢复稳定性 | 越小越稳定 |
| 最大恢复时间 | 最差状态 | 关注是否异常 |
| 相关系数 | 距离/配速影响 | >0.5 显著相关 |
进阶:连续恢复时间监控
# 计算滚动平均(3次慢跑窗口)
df['滚动平均'] = df['恢复时间_min'].rolling(window=3).mean()
# 检测连续上升趋势(疲劳累积)
df['变化'] = df['恢复时间_min'].diff()
df['连续上升'] = (df['变化'] > 0).astype(int)
df['连续上升次数'] = df['连续上升'].groupby(
(df['连续上升'] != df['连续上升'].shift()).cumsum()
).cumsum()
print(df[['日期', '恢复时间_min', '滚动平均', '连续上升次数']].tail(10))
本案例演示了慢跑恢复时间的完整统计流程:
- 描述统计:均值、中位数、标准差、极值
- 分组分析:按距离、配速分组对比
- 相关性分析:找出影响恢复的关键因素
- 异常检测:IQR 和 Z-score 方法
- 可视化:趋势图、散点图、箱线图
- 报告输出:自动评价恢复等级和趋势
这套方法也可用于跑步、骑行等其他运动的恢复时间监控,如果需要处理真实心率数据(如从运动手表导出的 CSV),只需将 pd.read_csv() 替换模拟数据即可。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播