本文目录导读:

在足球数据分析(或其他球类运动)中,统计“长短传比例”通常涉及对传球数据的分类,由于“长传”和“短传”没有统一的国际标准,通常需要人为定义阈值(如距离超过25米或30米算长传)。
以下提供三种不同场景的实用脚本方案,从最直接的Python数据处理到可视化,你可以根据数据格式选择。
基于Python + Pandas(最通用)
适用场景:你有一份包含传球距离的表格数据(CSV/Excel),字段类似 passer, receiver, distance。
核心逻辑:设定阈值(threshold = 25),将距离分为“长传”和“短传”,然后统计组内比例。
import pandas as pd
import numpy as np
# --- 配置参数 ---
THRESHOLD = 25 # 单位:米,大于等于此值为长传
LONG_LABEL = '长传'
SHORT_LABEL = '短传'
# --- 加载数据(假设CSV有 distance 列) ---
# df = pd.read_csv('passing_data.csv')
# 为演示,创建模拟数据:
np.random.seed(42)
df = pd.DataFrame({
'player': np.random.choice(['A', 'B', 'C'], 100),
'distance': np.random.uniform(5, 50, 100) # 距离5-50米
})
# --- 分类函数 ---
def classify_pass(distance):
return LONG_LABEL if distance >= THRESHOLD else SHORT_LABEL
df['pass_type'] = df['distance'].apply(classify_pass)
# --- 统计全局比例 ---
global_counts = df['pass_type'].value_counts()
global_percent = df['pass_type'].value_counts(normalize=True) * 100
print("=== 全局长短传比例 ===")
print(f"总传球数: {len(df)}")
for label in [LONG_LABEL, SHORT_LABEL]:
if label in global_percent.index:
print(f"{label}: {global_counts[label]}次 ({global_percent[label]:.1f}%)")
# --- 统计每个球员的比例(按球员分组) ---
print("\n=== 各球员长短传分布 ===")
player_stats = df.groupby(['player', 'pass_type']).size().unstack(fill_value=0)
player_stats['总计'] = player_stats.sum(axis=1)
# 计算百分比(针对每行)
player_stats[LONG_LABEL + '_%'] = (player_stats[LONG_LABEL] / player_stats['总计'] * 100).round(1)
player_stats[SHORT_LABEL + '_%'] = (player_stats[SHORT_LABEL] / player_stats['总计'] * 100).round(1)
print(player_stats[[LONG_LABEL, SHORT_LABEL, LONG_LABEL+'_%', SHORT_LABEL+'_%']])
基于Python + Matplotlib(可视化分布)
适用场景:你想直观查看“距离”的连续分布,并自动用颜色划分长短传区域。
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 假设 df 已有 distance 列
# 此处直接用上面的模拟数据
# ...
# --- 绘制直方图 ---
plt.figure(figsize=(10, 5))
# 按分类分色绘图
plt.hist(df[df['pass_type'] == '长传']['distance'],
bins=15, alpha=0.7, color='red', label='长传 (>=25m)')
plt.hist(df[df['pass_type'] == '短传']['distance'],
bins=15, alpha=0.7, color='blue', label='短传 (<25m)')
# 画阈值线
plt.axvline(x=THRESHOLD, color='k', linestyle='--', linewidth=1,
label=f'阈值: {THRESHOLD}m')
plt.xlabel('传球距离 (米)')
plt.ylabel('传球次数')f'传球距离分布 (长短传比例: {global_percent[LONG_LABEL]:.1f}% vs {global_percent[SHORT_LABEL]:.1f}%)')
plt.legend()
plt.grid(axis='y', alpha=0.3)
plt.show()
纯SQL(针对数据库表)
适用场景:数据存在MySQL/PostgreSQL中,表结构为 passes(id, player_id, distance)。
-- 1. 设置阈值(如果你不想改代码,可以临时用WITH定义)
WITH params AS (SELECT 25 AS threshold)
-- 2. 计算全局统计
SELECT
CASE WHEN distance >= (SELECT threshold FROM params) THEN '长传' ELSE '短传' END AS pass_type,
COUNT(*) AS total_passes,
ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) AS percentage
FROM passes
GROUP BY pass_type;
-- 3. 如果需要按球员分组统计:
SELECT
player_id,
SUM(CASE WHEN distance >= 25 THEN 1 ELSE 0 END) AS long_pass_count,
SUM(CASE WHEN distance < 25 THEN 1 ELSE 0 END) AS short_pass_count,
ROUND(
100.0 * SUM(CASE WHEN distance >= 25 THEN 1 ELSE 0 END)
/ COUNT(*), 1
) AS long_pct
FROM passes
GROUP BY player_id
ORDER BY long_pct DESC;
附加建议:如何定义“长短传”?
如果你没有标准距离阈值,可以尝试以下两种动态方法:
- 基于百分位数:将传球距离按从大到小排序,前20%视为“长传”,后80%视为“短传”(利用
df['distance'].quantile(0.8))。 - 基于具体战术:将进入对方半场的传球算作长传,但需要额外的坐标数据(
x,y起始点和终点)。
# 替代方法:动态阈值(中位数或分位数) DYNAMIC_THRESHOLD = df['distance'].median() # 以中位数为界 # 或者按前80%分位: P80 = df['distance'].quantile(0.8)
运行说明
- 如果数据量大,建议使用
pandas的read_csv后直接运行方案一。 - 如果只需要一个比率,直接运行方案一打印结果即可。
- 如果数据是JSON格式(来自API),只需将
pd.read_csv替换为pd.DataFrame(data_list)。
如果提供具体的文件格式(如JSON、XML)或字段名,我可以进一步修改脚本。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播