Python案例:统计长短传比例如何分布
下面提供一个完整的Python案例,统计赛事/交易数据中长传(long pass)与短传(short pass)的比例分布情况。

场景说明
以足球比赛传球数据为例,按球员/球队统计:
- 短传:距离 < 25 米
- 长传:距离 ≥ 25 米
统计各球员(或球队)的长传占比分布,并可视化。
示例代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# ---------- 1. 构造模拟数据 ----------
np.random.seed(42)
players = [f"Player_{i}" for i in range(1, 21)]
data = []
for p in players:
total_passes = np.random.randint(30, 120) # 每人总传球数
long_ratio = np.random.beta(2, 5) # 长传比例(大多偏低)
long_passes = int(total_passes * long_ratio)
short_passes = total_passes - long_passes
data.append([p, total_passes, long_passes, short_passes])
df = pd.DataFrame(data, columns=["player", "total", "long", "short"])
# ---------- 2. 计算长短传比例 ----------
df["long_ratio"] = df["long"] / df["total"]
df["short_ratio"] = df["short"] / df["total"]
print("=== 各球员长短传比例 ===")
print(df.sort_values("long_ratio", ascending=False).to_string(index=False))
# ---------- 3. 分布统计 ----------
print("\n=== 长传比例分布统计 ===")
print(df["long_ratio"].describe())
# 按区间分箱统计人数
bins = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 1.0]
labels = ["0-10%", "10-20%", "20-30%", "30-40%", "40-50%", ">50%"]
df["bucket"] = pd.cut(df["long_ratio"], bins=bins, labels=labels, right=False)
bucket_count = df["bucket"].value_counts().reindex(labels)
print("\n=== 长传比例区间分布(人数) ===")
print(bucket_count)
# ---------- 4. 可视化 ----------
fig, axes = plt.subplots(1, 3, figsize=(16, 5))
# 直方图:长传比例分布
axes[0].hist(df["long_ratio"], bins=10, color="steelblue", edgecolor="black")
axes[0].axvline(df["long_ratio"].mean(), color="red", linestyle="--", label=f"均值={df['long_ratio'].mean():.2f}")
axes[0].set_title("长传比例分布直方图")
axes[0].set_xlabel("长传比例")
axes[0].set_ylabel("人数")
axes[0].legend()
# 条形图:区间分布
bucket_count.plot(kind="bar", ax=axes[1], color="coral", edgecolor="black")
axes[1].set_title("长传比例区间分布")
axes[1].set_xlabel("长传比例区间")
axes[1].set_ylabel("人数")
axes[1].tick_params(axis='x', rotation=45)
# 散点图:总传球数 vs 长传比例
axes[2].scatter(df["total"], df["long_ratio"], color="green", alpha=0.7)
axes[2].set_title("总传球数 vs 长传比例")
axes[2].set_xlabel("总传球数")
axes[2].set_ylabel("长传比例")
plt.tight_layout()
plt.savefig("pass_ratio_distribution.png", dpi=120)
plt.show()
运行结果示意
分布统计(describe):
| 指标 | 值 |
|---|---|
| mean | 约 0.28 |
| std | 约 0.14 |
| min | 05 |
| 25% | 18 |
| 50% | 26 |
| 75% | 38 |
| max | 55 |
区间分布(示例):
| 长传比例区间 | 人数 |
|---|---|
| 0-10% | 1 |
| 10-20% | 4 |
| 20-30% | 7 |
| 30-40% | 5 |
| 40-50% | 2 |
| >50% | 1 |
关键分析点
-
整体分布:呈右偏分布,多数球员长传比例集中在 20%~40%,短传为主。
-
按位置分析(可扩展):
# 若数据含 position 列 df.groupby("position")[["long_ratio","short_ratio"]].mean()- 后卫:长传比例高(常 >40%)
- 中场:短传为主(长传 <25%)
- 前锋:分布较分散
-
可视化建议:
- 直方图看整体形状
- 箱线图对比不同位置:
df.boxplot(column="long_ratio", by="position") - 饼图展示全队长短传总量占比
扩展:全队长短传统计
total_long = df["long"].sum()
total_short = df["short"].sum()
total = total_long + total_short
print(f"全队长传:{total_long} ({total_long/total:.1%})")
print(f"全队短传:{total_short} ({total_short/total:.1%})")
# 饼图
plt.pie([total_long, total_short],
labels=["长传", "短传"],
autopct="%1.1f%%",
colors=["#ff9999", "#66b3ff"])"全队长短传比例")
plt.show()
可复用要点
| 步骤 | 方法 |
|---|---|
| 计算比例 | long / total |
| 分布统计 | describe() |
| 分箱 | pd.cut() |
| 分组对比 | groupby().mean() |
| 可视化 | hist / bar / boxplot / pie |
需要我按具体数据字段(如传球距离、比赛事件表)帮你改写为真实数据版本吗?