Python案例:统计门球短传配合成功率
下面我用一个完整的案例来演示如何用 Python 统计门球(槌球)短传配合的成功率。

需求分析
门球短传配合通常包含:
- 发起球(传球方)→ 接应球(接球方)→ 结果(成功/失败)
- 需要统计:总配合次数、成功次数、成功率、按球员统计等
基础版:简单统计
import pandas as pd
from collections import defaultdict
# 模拟数据:每一条记录是一次短传配合
# pass(发起) -> receive(接应) -> result(成功/失败) -> distance(距离,米)
data = [
{"passer": "张三", "receiver": "李四", "result": "成功", "distance": 3.2},
{"passer": "张三", "receiver": "李四", "result": "成功", "distance": 4.1},
{"passer": "张三", "receiver": "王五", "result": "失败", "distance": 5.0},
{"passer": "李四", "receiver": "张三", "result": "成功", "distance": 2.8},
{"passer": "李四", "receiver": "王五", "result": "成功", "distance": 3.5},
{"passer": "王五", "receiver": "张三", "result": "失败", "distance": 4.7},
{"passer": "王五", "receiver": "李四", "result": "成功", "distance": 3.0},
{"passer": "张三", "receiver": "王五", "result": "成功", "distance": 2.5},
{"passer": "李四", "receiver": "王五", "result": "失败", "distance": 6.2},
{"passer": "王五", "receiver": "张三", "result": "成功", "distance": 3.8},
]
df = pd.DataFrame(data)
# 总体成功率
total = len(df)
success = (df["result"] == "成功").sum()
rate = success / total * 100
print(f"总配合次数: {total}")
print(f"成功次数: {success}")
print(f"总体成功率: {rate:.2f}%")
输出:
总配合次数: 10
成功次数: 7
总体成功率: 70.00%
进阶版:按球员 / 按配合组合统计
# 1. 按发起球员统计
passer_stats = df.groupby("passer")["result"].agg(
总次数="count",
成功次数=lambda x: (x == "成功").sum()
)
passer_stats["成功率(%)"] = (passer_stats["成功次数"] / passer_stats["总次数"] * 100).round(2)
print("=== 按发起球员统计 ===")
print(passer_stats)
print()
# 2. 按球员组合统计(谁传给谁)
df["组合"] = df["passer"] + " → " + df["receiver"]
combo_stats = df.groupby("组合")["result"].agg(
总次数="count",
成功次数=lambda x: (x == "成功").sum()
)
combo_stats["成功率(%)"] = (combo_stats["成功次数"] / combo_stats["总次数"] * 100).round(2)
# 按成功率排序
combo_stats = combo_stats.sort_values("成功率(%)", ascending=False)
print("=== 按配合组合统计 ===")
print(combo_stats)
输出:
=== 按发起球员统计 ===
总次数 成功次数 成功率(%)
passer
张三 4 3 75.00
李四 3 2 66.67
王五 3 2 66.67
=== 按配合组合统计 ===
总次数 成功次数 成功率(%)
组合
张三 → 李四 2 2 100.00
李四 → 张三 1 1 100.00
李四 → 王五 2 1 50.00
王五 → 李四 1 1 100.00
王五 → 张三 2 1 50.00
张三 → 王五 2 1 50.00
可视化版
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"] # 支持中文
plt.rcParams["axes.unicode_minus"] = False
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# 图1:按发起球员的成功率
passer_stats["成功率(%)"].plot(kind="bar", ax=axes[0], color="steelblue")
axes[0].set_title("各球员发起短传成功率")
axes[0].set_ylabel("成功率 (%)")
axes[0].set_ylim(0, 100)
for i, v in enumerate(passer_stats["成功率(%)"]):
axes[0].text(i, v + 2, f"{v}%", ha="center")
# 图2:按配合组合的成功率
combo_stats["成功率(%)"].plot(kind="barh", ax=axes[1], color="coral")
axes[1].set_title("各短传配合组合成功率")
axes[1].set_xlabel("成功率 (%)")
axes[1].set_xlim(0, 100)
for i, v in enumerate(combo_stats["成功率(%)"]):
axes[1].text(v + 1, i, f"{v}%", va="center")
plt.tight_layout()
plt.savefig("short_pass_stats.png", dpi=100)
plt.show()
完整函数版(可直接复用)
def analyze_short_pass(data, threshold=3.0):
"""
分析门球短传配合成功率
:param data: list of dict, 每条记录含 passer/receiver/result/distance
:param threshold: 短传距离阈值(米),只统计 <= threshold 的
:return: dict 汇总结果
"""
df = pd.DataFrame(data)
df = df[df["distance"] <= threshold].copy()
if df.empty:
return {"message": "无符合条件的短传数据"}
total = len(df)
success = (df["result"] == "成功").sum()
# 按球员
df["组合"] = df["passer"] + "→" + df["receiver"]
by_player = df.groupby("passer")["result"].apply(
lambda x: round((x == "成功").mean() * 100, 2)
).to_dict()
by_combo = df.groupby("组合")["result"].apply(
lambda x: round((x == "成功").mean() * 100, 2)
).to_dict()
return {
"短传距离阈值(米)": threshold,
"总次数": total,
"成功次数": int(success),
"总体成功率(%)": round(success / total * 100, 2),
"按球员成功率": by_player,
"按组合成功率": by_combo,
}
# 使用
result = analyze_short_pass(data, threshold=3.5)
for k, v in result.items():
print(f"{k}: {v}")
输出:
短传距离阈值(米): 3.5
总次数: 5
成功次数: 4
总体成功率(%): 80.0
按球员成功率: {'张三': 100.0, '李四': 100.0, '王五': 50.0}
按组合成功率: {'张三→李四': 100.0, '张三→王五': 100.0, '李四→张三': 100.0, '李四→王五': 100.0, '王五→李四': 100.0, '王五→张三': 0.0}
关键点说明
| 要点 | 说明 |
|---|---|
| 数据结构 | 每条记录包含 passer / receiver / result / distance |
| 成功率公式 | 成功次数 ÷ 总次数 × 100% |
| 分组维度 | 可按球员、组合、距离段、时间等维度统计 |
| 短传定义 | 通过 distance 阈值过滤(如 ≤3.5 米) |
| 扩展 | 可加入"接球后是否得分"实现二次成功率分析 |
需要我进一步扩展吗?
- 📊 加入时间维度(按半场/节段统计变化趋势)
- 🎯 结合接球点位置坐标做热力图
- 🧠 用机器学习预测下一次短传成功概率