本文目录导读:

我来为您提供一个完整的Python案例,用于统计和分析慢跑恢复时间数据。
慢跑恢复时间数据分析案例
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
class RunningRecoveryAnalyzer:
"""慢跑恢复时间分析器"""
def __init__(self):
self.data = None
self.recovery_data = None
def generate_sample_data(self, num_days=90):
"""生成模拟数据"""
np.random.seed(42)
dates = [datetime.now().date() - timedelta(days=i) for i in range(num_days)]
# 生成模拟数据
self.data = pd.DataFrame({
'date': dates,
'distance': np.random.normal(5, 1.5, num_days).clip(2, 10), # 跑步距离(km)
'duration': np.random.normal(30, 8, num_days).clip(15, 60), # 跑步时长(分钟)
'avg_heart_rate': np.random.normal(150, 15, num_days).clip(120, 180), # 平均心率
'max_heart_rate': np.random.normal(165, 15, num_days).clip(140, 195), # 最大心率
'sleep_hours': np.random.normal(7, 1.5, num_days).clip(4, 10), # 前晚睡眠
'previous_recovery': np.random.normal(72, 24, num_days).clip(24, 168), # 之前恢复时间(小时)
'hydration': np.random.normal(3, 1, num_days).clip(1, 5), # hydration level 1-5
'stress_level': np.random.randint(1, 6, num_days), # 压力指数 1-5
'muscle_soreness': np.random.randint(0, 11, num_days) # 肌肉酸痛程度 0-10
})
# 计算恢复时间(基于多个因素)
base_recovery = 48 + self.data['distance'] * 2
hr_factor = (self.data['avg_heart_rate'] - 140) * 0.5
sleep_factor = (7 - self.data['sleep_hours']) * 3
stress_factor = self.data['stress_level'] * 2
soreness_factor = self.data['muscle_soreness'] * 0.3
self.data['recovery_time'] = (base_recovery + hr_factor + sleep_factor +
stress_factor + soreness_factor +
np.random.normal(0, 5, num_days)).clip(24, 168)
# 计算恢复状态
self.data['recovery_level'] = np.select(
[self.data['recovery_time'] >= 72,
self.data['recovery_time'] >= 48,
self.data['recovery_time'] >= 24,
self.data['recovery_time'] < 24],
['需要充分休息', '中等恢复', '恢复良好', '完全恢复'],
default='未知'
)
return self.data
def load_real_data(self, filepath):
"""加载真实数据"""
self.data = pd.read_csv(filepath)
return self.data
def calculate_basic_stats(self):
"""计算基本统计指标"""
stats = {
'平均恢复时间': self.data['recovery_time'].mean(),
'中位数恢复时间': self.data['recovery_time'].median(),
'最短恢复时间': self.data['recovery_time'].min(),
'最长恢复时间': self.data['recovery_time'].max(),
'恢复时间标准差': self.data['recovery_time'].std(),
'平均跑步距离': self.data['distance'].mean(),
'平均心率': self.data['avg_heart_rate'].mean(),
'平均睡眠时长': self.data['sleep_hours'].mean()
}
return pd.Series(stats)
def analyze_factors(self):
"""分析影响恢复时间的因素"""
# 相关性分析
correlations = self.data[['distance', 'duration', 'avg_heart_rate',
'max_heart_rate', 'sleep_hours', 'hydration',
'stress_level', 'muscle_soreness', 'recovery_time']].corr()
# 分组分析
grouping = self.data.groupby('recovery_level')[['recovery_time', 'distance',
'avg_heart_rate', 'sleep_hours',
'stress_level', 'muscle_soreness']].mean()
return correlations, grouping
def visualize_recovery(self):
"""可视化恢复数据"""
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 恢复时间分布
axes[0, 0].hist(self.data['recovery_time'], bins=20, alpha=0.7,
color='skyblue', edgecolor='black')
axes[0, 0].set_title('恢复时间分布')
axes[0, 0].set_xlabel('恢复时间(小时)')
axes[0, 0].set_ylabel('频次')
axes[0, 0].axvline(self.data['recovery_time'].mean(),
color='red', linestyle='--', label='平均值')
axes[0, 0].legend()
# 2. 恢复状态占比
recovery_counts = self.data['recovery_level'].value_counts()
axes[0, 1].pie(recovery_counts.values, labels=recovery_counts.index,
autopct='%1.1f%%', shadow=True)
axes[0, 1].set_title('恢复状态占比')
# 3. 恢复时间趋势
self.data['date'] = pd.to_datetime(self.data['date'])
axes[1, 0].plot(self.data['date'], self.data['recovery_time'],
marker='o', alpha=0.6, color='green')
axes[1, 0].set_title('恢复时间变化趋势')
axes[1, 0].set_xlabel('日期')
axes[1, 0].set_ylabel('恢复时间(小时)')
axes[1, 0].grid(True, alpha=0.3)
# 4. 恢复时间与关键因素的关系
scatter = axes[1, 1].scatter(self.data['distance'], self.data['recovery_time'],
c=self.data['avg_heart_rate'], cmap='RdYlBu_r',
alpha=0.7, s=80)
axes[1, 1].set_title('恢复时间与跑步距离、心率关系')
axes[1, 1].set_xlabel('跑步距离(km)')
axes[1, 1].set_ylabel('恢复时间(小时)')
plt.colorbar(scatter, ax=axes[1, 1], label='平均心率')
plt.suptitle('慢跑恢复时间数据分析', fontsize=16, weight='bold')
plt.tight_layout()
plt.show()
def analyze_feature_importance(self):
"""分析特征重要性"""
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler
# 准备数据
features = ['distance', 'duration', 'avg_heart_rate', 'max_heart_rate',
'sleep_hours', 'hydration', 'stress_level', 'muscle_soreness']
X = self.data[features]
y = self.data['recovery_time']
# 标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 随机森林回归
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(X_scaled, y)
# 特征重要性
importance_df = pd.DataFrame({
'feature': features,
'importance': rf.feature_importances_
}).sort_values('importance', ascending=False)
return importance_df
def predict_recovery_time(self, input_data):
"""预测恢复时间"""
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
features = ['distance', 'duration', 'avg_heart_rate', 'max_heart_rate',
'sleep_hours', 'hydration', 'stress_level', 'muscle_soreness']
X = self.data[features]
y = self.data['recovery_time']
# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练模型
model = LinearRegression()
model.fit(X_train, y_train)
# 预测
input_df = pd.DataFrame([input_data], columns=features)
prediction = model.predict(input_df)[0]
# 模型评估
from sklearn.metrics import mean_squared_error, r2_score
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
return prediction, {'MSE': mse, 'R2': r2}
def weekly_analysis(self):
"""周分析"""
self.data['week'] = pd.to_datetime(self.data['date']).dt.isocalendar().week
weekly_stats = self.data.groupby('week').agg({
'recovery_time': ['mean', 'std', 'min', 'max'],
'distance': 'sum',
'avg_heart_rate': 'mean',
'sleep_hours': 'mean'
}).round(2)
return weekly_stats
def generate_report(self):
"""生成分析报告"""
print("=" * 60)
print("慢跑恢复时间数据分析报告")
print("=" * 60)
# 基本统计
stats = self.calculate_basic_stats()
print("\n【基本统计指标】")
print(stats.to_string())
# 恢复状态分布
print("\n【恢复状态分布】")
recovery_dist = self.data['recovery_level'].value_counts()
print(recovery_dist.to_string())
# 特征重要性
print("\n【影响因素重要性排序】")
importance = self.analyze_feature_importance()
print(importance.to_string(index=False))
# 周统计
print("\n【周统计数据】")
weekly = self.weekly_analysis()
print(weekly.to_string())
print("\n【建议】")
print("1. 如果平均恢复时间超过72小时,建议适当降低训练强度")
print("2. 保证充足的睡眠(7小时以上)有助于缩短恢复时间")
print("3. 注意监测心率和肌肉酸痛程度")
print("4. 合理安排训练计划,避免过度训练")
def main():
"""主函数"""
# 创建分析器
analyzer = RunningRecoveryAnalyzer()
# 生成或加载数据
print("1. 使用模拟数据进行分析")
print("2. 从文件加载数据")
choice = input("请选择(1或2): ")
if choice == '2':
filepath = input("请输入数据文件路径: ")
try:
analyzer.load_real_data(filepath)
print("数据加载成功!")
except Exception as e:
print(f"数据加载失败: {e}")
print("使用模拟数据代替...")
analyzer.generate_sample_data()
else:
analyzer.generate_sample_data(90) # 生成90天数据
print("模拟数据生成完成!")
# 生成报告
analyzer.generate_report()
# 可视化
print("\n生成可视化图表...")
analyzer.visualize_recovery()
# 预测示例
print("\n【预测恢复时间示例】")
sample_input = {
'distance': 5.0,
'duration': 30,
'avg_heart_rate': 155,
'max_heart_rate': 175,
'sleep_hours': 6.5,
'hydration': 3,
'stress_level': 3,
'muscle_soreness': 5
}
prediction, metrics = analyzer.predict_recovery_time(sample_input)
print(f"预测恢复时间: {prediction:.1f} 小时")
print(f"模型性能: R² = {metrics['R2']:.3f}, MSE = {metrics['MSE']:.2f}")
# 保存数据
save = input("\n是否保存分析结果到文件? (y/n): ")
if save.lower() == 'y':
analyzer.data.to_csv('running_recovery_data.csv', index=False)
importance = analyzer.analyze_feature_importance()
importance.to_csv('feature_importance.csv', index=False)
weekly = analyzer.weekly_analysis()
weekly.to_csv('weekly_stats.csv')
print("分析结果已保存!")
print("\n分析完成!")
if __name__ == "__main__":
main()
补充的分析功能类
class AdvancedRecoveryAnalyzer:
"""高级恢复时间分析"""
def analyze_recovery_patterns(self, data):
"""分析恢复模式"""
# 时间段分析
data['hour'] = data['date'].dt.hour
# 趋势分析
data['rolling_mean'] = data['recovery_time'].rolling(window=7).mean()
data['rolling_std'] = data['recovery_time'].rolling(window=7).std()
# 异常检测
mean_rec = data['recovery_time'].mean()
std_rec = data['recovery_time'].std()
data['is_anomaly'] = abs(data['recovery_time'] - mean_rec) > 2 * std_rec
return data
def correlation_heatmap(self, data):
"""绘制相关性热图"""
plt.figure(figsize=(10, 8))
numeric_cols = data.select_dtypes(include=[np.number]).columns
correlation_matrix = data[numeric_cols].corr()
mask = np.triu(np.ones_like(correlation_matrix, dtype=bool))
sns.heatmap(correlation_matrix, mask=mask, annot=True, fmt='.2f',
cmap='coolwarm', center=0, square=True)
plt.title('恢复时间影响因素相关性分析')
plt.tight_layout()
plt.show()
def recovery_optimization_tips(self, data):
"""生成恢复优化建议"""
tips = []
# 分析关键因素
avg_sleep = data['sleep_hours'].mean()
if avg_sleep < 7:
tips.append(f"平均睡眠时间不足({avg_sleep:.1f}小时),建议增加到7-8小时")
avg_stress = data['stress_level'].mean()
if avg_stress > 3:
tips.append(f"压力指数较高({avg_stress:.1f}/5),建议进行冥想或拉伸放松")
avg_soreness = data['muscle_soreness'].mean()
if avg_soreness > 5:
tips.append(f"肌肉酸痛程度较高({avg_soreness:.1f}/10),建议增加恢复训练")
high_hr_days = (data['avg_heart_rate'] > 160).sum()
if high_hr_days > 10:
tips.append(f"有{high_hr_days}天心率高于160bpm,建议降低训练强度")
return tips
使用说明
-
数据准备:运行代码会生成90天的模拟数据,或者可以自定义CSV格式的数据文件
-
主要功能:
- 恢复时间统计与分布分析
- 影响因素相关性分析
- 机器学习预测
- 可视化展示
- 周度/月度趋势分析
- 异常检测
-
输出结果:
- 基本统计指标
- 可视化图表
- 特征重要性排序
- 恢复预测模型
- 优化建议
这个案例可以帮助跑步爱好者分析自己的恢复情况,了解影响恢复时间的因素,并给出针对性的训练和休息建议。