本文目录导读:

我来为您提供一个统计长短传比例分布的Python案例。
基础版本:简单统计分析
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
# 示例数据:模拟传球数据
def generate_sample_data():
"""生成模拟传球数据"""
np.random.seed(42)
# 生成1000个传球数据
passes = []
for i in range(1000):
# 随机生成传球距离(5-50米)
distance = np.random.uniform(5, 50)
# 根据距离分类
if distance <= 15:
pass_type = '短传'
elif distance <= 25:
pass_type = '中传'
else:
pass_type = '长传'
passes.append({
'player_id': np.random.randint(1, 20),
'distance': distance,
'pass_type': pass_type,
'success': np.random.choice([True, False], p=[0.85, 0.15])
})
return pd.DataFrame(passes)
# 统计分析函数
def analyze_pass_distribution(df):
"""分析传球类型分布"""
print("="*60)
print("传球类型分布统计")
print("="*60)
# 总体分布
type_counts = df['pass_type'].value_counts()
type_percentages = df['pass_type'].value_counts(normalize=True) * 100
print("\n📊 传球类型总体分布:")
for pass_type in ['短传', '中传', '长传']:
if pass_type in type_counts.index:
count = type_counts[pass_type]
percentage = type_percentages[pass_type]
print(f" {pass_type}: {count}次 ({percentage:.1f}%)")
# 按球员统计
print("\n👥 按球员统计:")
player_stats = df.groupby('player_id').agg({
'pass_type': ['count', lambda x: (x == '短传').sum(),
lambda x: (x == '长传').sum()]
}).round(2)
# 计算比例
for player in df['player_id'].unique():
player_data = df[df['player_id'] == player]
total = len(player_data)
short_passes = len(player_data[player_data['pass_type'] == '短传'])
long_passes = len(player_data[player_data['pass_type'] == '长传'])
if total > 0:
short_ratio = short_passes / total * 100
long_ratio = long_passes / total * 100
print(f" 球员{player}: 短传{short_ratio:.1f}% / 长传{long_ratio:.1f}%")
return type_counts, type_percentages
# 创建图表
def plot_distribution(df):
"""创建图表展示分布"""
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 传球类型饼图
ax1 = axes[0, 0]
type_counts = df['pass_type'].value_counts()
type_counts.plot.pie(
ax=ax1,
autopct='%1.1f%%',
colors=['#4CAF50', '#FFC107', '#FF5722']
)
ax1.set_title('传球类型分布')
# 2. 传球距离分布直方图
ax2 = axes[0, 1]
colors = ['green' if t == '短传' else 'orange' if t == '中传' else 'red'
for t in df['pass_type']]
ax2.hist(df['distance'], bins=30, color='steelblue', alpha=0.6)
ax2.axvline(x=15, color='green', linestyle='--', alpha=0.8, label='短传阈值')
ax2.axvline(x=25, color='red', linestyle='--', alpha=0.8, label='长传阈值')
ax2.set_xlabel('传球距离(米)')
ax2.set_ylabel('频次')
ax2.set_title('传球距离分布')
ax2.legend()
# 3. 球员传球风格散点图
ax3 = axes[1, 0]
player_short_ratio = []
player_long_ratio = []
for player in df['player_id'].unique():
player_data = df[df['player_id'] == player]
if len(player_data) > 0:
short_ratio = len(player_data[player_data['pass_type'] == '短传']) / len(player_data) * 100
long_ratio = len(player_data[player_data['pass_type'] == '长传']) / len(player_data) * 100
player_short_ratio.append(short_ratio)
player_long_ratio.append(long_ratio)
ax3.scatter(player_short_ratio, player_long_ratio, alpha=0.6)
ax3.set_xlabel('短传比例 (%)')
ax3.set_ylabel('长传比例 (%)')
ax3.set_title('球员传球风格')
# 4. 短传成功率对比
ax4 = axes[1, 1]
success_rates = df.groupby('pass_type')['success'].mean() * 100
success_rates.plot(kind='bar', ax=ax4, color=['#4CAF50', '#FFC107', '#FF5722'])
ax4.set_title('各类型传球成功率')
ax4.set_xlabel('传球类型')
ax4.set_ylabel('成功率 (%)')
ax4.set_ylim(80, 100)
plt.tight_layout()
plt.show()
# 主执行
if __name__ == "__main__":
# 生成数据
df = generate_sample_data()
# 统计分析
analyze_pass_distribution(df)
# 绘制图表
plot_distribution(df)
# 输出详细统计结果
print("\n📊 详细统计结果:")
print(df.groupby('pass_type').agg({
'distance': ['mean', 'std', 'min', 'max'],
'success': 'mean'
}).round(2))
进阶版本:更复杂的分析
import pandas as pd
import numpy as np
from scipy import stats
class PassAnalyzer:
"""传球数据高级分析器"""
def __init__(self, data):
self.df = data
self.calculate_metrics()
def calculate_metrics(self):
"""计算高级指标"""
self.df['pass_precision'] = np.random.uniform(70, 95, len(self.df)) # 传球精度
# 计算传球稳定性
self.df['pass_risk'] = self.df['distance'].apply(
lambda x: 0.1 if x < 10 else 0.3 if x < 20 else 0.5
)
def statistical_tests(self):
"""统计检验"""
print("\n🧪 统计检验结果:")
# 短传和长传距离的显著性检验
short_passes = self.df[self.df['pass_type'] == '短传']['pass_precision']
long_passes = self.df[self.df['pass_type'] == '长传']['pass_precision']
t_stat, p_value = stats.ttest_ind(short_passes, long_passes)
print(f"短传vs长传精度t检验: t={t_stat:.3f}, p={p_value:.3f}")
# 卡方检验
contingency_table = pd.crosstab(self.df['pass_type'], self.df['success'])
chi2, chi2_p, dof, expected = stats.chi2_contingency(contingency_table)
print(f"卡方检验: χ²={chi2:.3f}, p={chi2_p:.3f}")
def compare_players(self):
"""比较不同球员的传球风格"""
print("\n🏃 球员传球风格比较:")
player_summary = []
for player in self.df['player_id'].unique():
player_data = self.df[self.df['player_id'] == player]
if len(player_data) >= 10: # 确保样本量
avg_distance = player_data['distance'].mean()
success_rate = player_data['success'].mean() * 100
short_count = len(player_data[player_data['pass_type'] == '短传'])
long_count = len(player_data[player_data['pass_type'] == '长传'])
player_summary.append({
'player_id': player,
'avg_distance': avg_distance,
'success_rate': success_rate,
'short_passes': short_count,
'long_passes': long_count,
'short_ratio': short_count / len(player_data) * 100,
'long_ratio': long_count / len(player_data) * 100
})
summary_df = pd.DataFrame(player_summary)
print(summary_df.to_string(index=False))
return summary_df
def generate_report(self):
"""生成综合报告"""
print("\n" + "="*60)
print("🗒️ 传球数据分析报告")
print("="*60)
# 总体统计
print(f"\n📈 总体统计指标:")
print(f" - 总传球数: {len(self.df)}")
print(f" - 平均传球距离: {self.df['distance'].mean():.2f}米")
print(f" - 传球成功率: {self.df['success'].mean()*100:.1f}%")
# 类型分布
print(f"\n🎯 类型分布:")
for pass_type in ['短传', '中传', '长传']:
count = len(self.df[self.df['pass_type'] == pass_type])
percentage = count / len(self.df) * 100
print(f" - {pass_type}: {percentage:.1f}% ({count}次)")
# 推荐建议
print(f"\n💡 分析建议:")
short_ratio = len(self.df[self.df['pass_type'] == '短传']) / len(self.df) * 100
if short_ratio > 60:
print(" - 球队偏向短传控制型打法")
elif short_ratio < 40:
print(" - 球队偏向长传进攻型打法")
else:
print(" - 球队打法较为均衡")
# 使用示例
if __name__ == "__main__":
# 生成测试数据
df = generate_sample_data()
# 创建分析对象
analyzer = PassAnalyzer(df)
# 执行分析
analyzer.statistical_tests()
analyzer.compare_players()
analyzer.generate_report()
可视化增强版本
import seaborn as sns
from matplotlib.colors import LinearSegmentedColormap
# 高级可视化
def advanced_visualization(df):
"""高级可视化分析"""
fig, axes = plt.subplots(3, 2, figsize=(18, 14))
# 1. 热力图:球员×传球类型
ax1 = axes[0, 0]
pivot_table = df.pivot_table(
index='player_id',
columns='pass_type',
values='distance',
aggfunc='count'
).fillna(0)
sns.heatmap(pivot_table, ax=ax1, annot=True, cmap='YlOrRd', fmt='g')
ax1.set_title('球员传球类型热力图')
# 2. 箱线图:传球距离分布
ax2 = axes[0, 1]
sns.boxplot(data=df, x='pass_type', y='distance', ax=ax2,
palette=['#4CAF50', '#FFC107', '#FF5722'])
ax2.set_title('各类型传球距离分布')
# 3. 时间序列(如果有多场比赛数据)
ax3 = axes[1, 0]
if 'match_id' not in df.columns:
df['match_id'] = 1 # 默认单场
match_stats = df.groupby(['match_id', 'pass_type']).size().unstack().fillna(0)
match_stats.plot(kind='line', ax=ax3, marker='o')
ax3.set_title('比赛传球类型趋势')
# 4. 雷达图:球员综合能力
ax4 = axes[1, 1]
# 选择一个典型球员示例
player = df.iloc[0]['player_id']
player_data = df[df['player_id'] == player]
categories = ['短传', '中传', '长传', '成功率', '平均距离']
values = [
len(player_data[player_data['pass_type'] == '短传']) / len(player_data) * 20,
len(player_data[player_data['pass_type'] == '中传']) / len(player_data) * 20,
len(player_data[player_data['pass_type'] == '长传']) / len(player_data) * 20,
player_data['success'].mean() * 20,
player_data['distance'].mean() / 5
]
angles = np.linspace(0, 2 * np.pi, len(categories), endpoint=False).tolist()
values += values[:1]
angles += angles[:1]
ax4 = plt.subplot(3, 2, 4, polar=True)
ax4.plot(angles, values)
ax4.fill(angles, values, alpha=0.3)
ax4.set_xticks(angles[:-1])
ax4.set_xticklabels(categories)
ax4.set_title(f'球员{player}能力雷达图')
# 5. 密度图:传球距离概率密度
ax5 = axes[2, 0]
for pass_type in ['短传', '中传', '长传']:
subset = df[df['pass_type'] == pass_type]
sns.kdeplot(subset['distance'], ax=ax5, label=pass_type, shade=True)
ax5.set_title('传球距离概率密度分布')
# 6. 相关性矩阵
ax6 = axes[2, 1]
numeric_df = df[['distance', 'pass_precision', 'pass_risk', 'success']]
corr_matrix = numeric_df.corr()
sns.heatmap(corr_matrix, ax=ax6, annot=True, cmap='coolwarm', fmt='.2f')
ax6.set_title('传球指标相关性矩阵')
plt.tight_layout()
plt.show()
这个案例包含了:
- 基础统计分析:传球类型分布、比例计算
- 高级分析:统计检验、球员风格比较
- 多样化可视化:饼图、直方图、热力图、雷达图等
您可以根据实际数据格式调整字段名和阈值标准,需要更具体的功能吗?
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播