Python案例:统计足球比赛中"挑球过人"次数
下面我用一个完整的案例,演示如何统计球员/球队的"挑球过人"次数,并判断多不多。

场景说明
假设我们有一份足球比赛事件数据(模拟数据),每条记录包含:球员、动作类型、时间等,我们要统计每个球员的挑球过人次数。
完整代码
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
# 1. 模拟比赛事件数据
data = [
{"球员": "梅西", "动作": "挑球过人", "时间": "12:30"},
{"球员": "梅西", "动作": "传球", "时间": "13:10"},
{"球员": "梅西", "动作": "挑球过人", "时间": "25:00"},
{"球员": "梅西", "动作": "射门", "时间": "30:15"},
{"球员": "梅西", "动作": "挑球过人", "时间": "45:00"},
{"球员": "姆巴佩", "动作": "挑球过人", "时间": "15:20"},
{"球员": "姆巴佩", "动作": "带球", "时间": "18:00"},
{"球员": "姆巴佩", "动作": "挑球过人", "时间": "60:40"},
{"球员": "维尼修斯","动作": "挑球过人","时间": "22:00"},
{"球员": "维尼修斯","动作": "传球", "时间": "33:00"},
{"球员": "哈兰德", "动作": "射门", "时间": "40:00"},
{"球员": "哈兰德", "动作": "挑球过人", "时间": "55:10"},
{"球员": "梅西", "动作": "挑球过人", "时间": "70:00"},
{"球员": "姆巴佩", "动作": "挑球过人", "时间": "80:00"},
]
df = pd.DataFrame(data)
# 2. 筛选出"挑球过人"事件
rainbow_flick = df[df["动作"] == "挑球过人"]
# 3. 按球员统计次数
stats = rainbow_flick["球员"].value_counts().reset_index()
stats.columns = ["球员", "挑球过人次数"]
print("=" * 40)
print("挑球过人次数统计")
print("=" * 40)
print(stats)
# 4. 判断"多不多"
total = len(rainbow_flick)
avg = stats["挑球过人次数"].mean()
max_player = stats.iloc[0]
print(f"\n总挑球过人次数: {total}")
print(f"人均挑球过人次数: {avg:.2f}")
print(f"最多球员: {max_player['球员']} ({max_player['挑球过人次数']}次)")
# 判定规则
def judge(n):
if n >= 4:
return "非常多 ⭐⭐⭐"
elif n >= 2:
return "较多 ⭐⭐"
elif n == 1:
return "一般 ⭐"
else:
return "很少"
print("\n每个球员的判定:")
for _, row in stats.iterrows():
print(f" {row['球员']}: {row['挑球过人次数']}次 -> {judge(row['挑球过人次数'])}")
# 5. 可视化
plt.rcParams["font.sans-serif"] = ["SimHei"] # 中文显示
plt.rcParams["axes.unicode_minus"] = False
plt.figure(figsize=(8, 5))
plt.bar(stats["球员"], stats["挑球过人次数"], color="skyblue")"球员挑球过人次数对比")
plt.xlabel("球员")
plt.ylabel("次数")
for i, v in enumerate(stats["挑球过人次数"]):
plt.text(i, v + 0.05, str(v), ha="center")
plt.tight_layout()
plt.show()
运行结果
========================================
挑球过人次数统计
========================================
球员 挑球过人次数
0 梅西 4
1 姆巴佩 3
2 维尼修斯 1
3 哈兰德 1
总挑球过人次数: 9
人均挑球过人次数: 2.25
最多球员: 梅西 (4次)
每个球员的判定:
梅西: 4次 -> 非常多 ⭐⭐⭐
姆巴佩: 3次 -> 较多 ⭐⭐
维尼修斯: 1次 -> 一般 ⭐
哈兰德: 1次 -> 一般 ⭐
如何判断"多不多"?
实际分析时可以从三个维度判断:
| 维度 | 方法 | 示例 |
|---|---|---|
| 横向对比 | 与同场其他球员比较 | 梅西4次 >> 人均2.25次,算多 |
| 纵向对比 | 与球员历史场均比较 | 梅西赛季场均1.8次,本场4次算爆发 |
| 基准判断 | 设定阈值 | ≥3次为"多",≥5次为"非常多" |
进阶:与历史数据对比
# 球员赛季场均挑球过人次数(基准值)
season_avg = {"梅西": 1.8, "姆巴佩": 2.1, "维尼修斯": 1.5, "哈兰德": 0.6}
stats["赛季场均"] = stats["球员"].map(season_avg)
stats["是否高于平均"] = stats["挑球过人次数"] > stats["赛季场均"]
stats["倍数"] = (stats["挑球过人次数"] / stats["赛季场均"]).round(2)
print(stats)
# 判断结论
for _, row in stats.iterrows():
if row["是否高于平均"]:
print(f"{row['球员']}本场挑球过人是他赛季平均的 {row['倍数']} 倍,偏多!")
else:
print(f"{row['球员']}本场挑球过人低于赛季平均,偏少。")
输出:
球员 挑球过人次数 赛季场均 是否高于平均 倍数
0 梅西 4 1.8 True 2.22
1 姆巴佩 3 2.1 True 1.43
2 维尼修斯 1 1.5 False 0.67
3 哈兰德 1 0.6 True 1.67
梅西本场挑球过人是他赛季平均的 2.22 倍,偏多!
姆巴佩本场挑球过人是他赛季平均的 1.43 倍,偏多!
维尼修斯本场挑球过人低于赛季平均,偏少。
哈兰德本场挑球过人是他赛季平均的 1.67 倍,偏多!
统计"挑球过人次数多不多"的核心思路:
- 数据收集 → 用 pandas 处理事件数据
- 筛选统计 →
value_counts()按球员聚合 - 判断标准 → 阈值法 / 横向对比 / 历史均值对比
- 可视化 → 柱状图直观展示
- 结论输出 → 给出"多/少"的判断
如果你有真实的比赛数据(如 Opta、StatsBomb 格式),把数据替换进去即可直接运行,需要我帮你处理具体格式的数据吗?