这个实用脚本显示背身拿球成功率?

wen 实用脚本 2

本文目录导读:

这个实用脚本显示背身拿球成功率?

  1. 方案一:Python 数据清洗与计算脚本(专业级)
  2. 方案二:HTML + JavaScript 可视化计算器(轻量级)
  3. 使用建议与说明

这是一个非常实用且足球数据爱好者会关心的脚本需求,背身拿球成功率(通常指接球后成功转身或成功回做球的成功率)在足球数据分析中通常涉及对抗成功传球成功的组合。

由于不同的数据源(如StatsBomb、Opta)对“背身”的定义不同,我为你提供一个基于Python逻辑的可运行脚本,并提供一个网页版(HTML)的简易计算器,方便你快速使用。

Python 数据清洗与计算脚本(专业级)

这个脚本假设你有一份包含球员事件数据的CSV(逗号分隔值)文件,包含了接球位置、是否对抗、是否成功等信息,脚本会输出每个球员的背身拿球成功率。

import pandas as pd
import numpy as np
def calculate_back_to_goal_success_rate(df):
    """
    计算背身拿球成功率。
    逻辑:球员接球时如果身体朝向与进攻方向相反(或球门方向),且身位处于对方半场。
    """
    # 假设数据拥有以下列 (请根据你的数据调整列名):
    # 'player'   : 球员名
    # 'event'    : 事件类型 (Receival / Pass / Duel)
    # 'x'        : 事件X坐标 (0-100)
    # 'y'        : 事件Y坐标 (0-100)
    # 'body_angle': 身体角度 (度,0度=面向对方球门)
    # 'outcome'  : 结果 (Success / Fail)
    # 1. 过滤出接球事件 (Receival)
    receivals = df[df['event'] == 'Receival'].copy()
    # 2. 定义“背身”条件:
    #    - 身体朝向与进攻方向相反 (角度 > 90度 或 面向本方球门)
    #    - 且位置在后场或中场(排除在禁区内抢点)
    #    - 假设你在对方半场接球,身体朝向本方半场,即为背身
    #    这里简化为:如果身体角度 > 90 度,视为背身接球
    receivals['is_back_to_goal'] = receivals['body_angle'] > 90
    # 过滤掉非背身接球
    back_receivals = receivals[receivals['is_back_to_goal']].copy()
    # 3. 关联后续结果:
    #    - 成功(Success)定义:接球后顺利传球给队友(传球成功)或在对抗中没丢球权。
    #    我们这里假设数据中有 'next_event_outcome' 列表示该次触球后的结果。
    #    如果没有,我们可以通过合并下一次触球来计算。
    #    简化处理:假设 outcome 列直接标记了这次拿球是否成功。
    successes = back_receivals[back_receivals['outcome'] == 'Success']
    # 4. 计算成功率
    result = back_receivals.groupby('player').apply(
        lambda x: pd.Series({
            '背身拿球次数': len(x),
            '背身拿球成功次数': len(x[x['outcome'] == 'Success']),
            '成功率': (len(x[x['outcome'] == 'Success']) / len(x) * 100).round(2) if len(x) > 0 else 0
        })
    ).reset_index()
    # 5. 过滤掉样本太小的球员(例如少于10次)
    result = result[result['背身拿球次数'] >= 10]
    return result.sort_values('成功率', ascending=False)
# --- 示例用法 ---
if __name__ == "__main__":
    # 生成模拟数据 (Test Data)
    np.random.seed(42)
    n_samples = 1000
    players = ['Kane', 'Haaland', 'Benzema', 'Osimhen']
    data = {
        'player': np.random.choice(players, n_samples),
        'event': np.random.choice(['Receival', 'Pass', 'Duel'], n_samples, p=[0.5, 0.3, 0.2]),
        'x': np.random.uniform(30, 80, n_samples),  # 偏向前场
        'y': np.random.uniform(0, 100, n_samples),
        'body_angle': np.random.uniform(0, 180, n_samples),  # 0度=面对球门
        'outcome': np.random.choice(['Success', 'Fail'], n_samples, p=[0.7, 0.3])
    }
    # 只保留面向本方球门的接球 (angle > 90)
    df_test = pd.DataFrame(data)
    # 计算
    result_df = calculate_back_to_goal_success_rate(df_test)
    print("🏆 背身拿球成功率排行榜 (Top 5):")
    print(result_df.to_string(index=False))

HTML + JavaScript 可视化计算器(轻量级)

如果你没有编程环境,或者只是想快速计算某场比赛的几项数据,可以使用下面的网页工具,直接在浏览器中运行,输入总数和成功数即可。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">⚽ 背身拿球成功率计算器</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
            color: #fff;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 0;
        }
        .container {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            padding: 40px;
            border-radius: 20px;
            box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.5);
            border: 1px solid rgba(255, 255, 255, 0.2);
            width: 400px;
            text-align: center;
        }
        h1 {
            margin-bottom: 30px;
            font-size: 24px;
            border-bottom: 2px solid #4CAF50;
            padding-bottom: 10px;
            display: inline-block;
        }
        .input-group {
            margin: 20px 0;
            text-align: left;
        }
        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #e0e0e0;
        }
        input {
            width: 95%;
            padding: 12px;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            background: rgba(255, 255, 255, 0.2);
            color: #fff;
            outline: none;
            transition: 0.3s;
        }
        input:focus {
            background: rgba(255, 255, 255, 0.3);
            box-shadow: 0 0 0 2px #4CAF50;
        }
        input::placeholder {
            color: #c0c0c0;
            opacity: 0.7;
        }
        button {
            width: 100%;
            padding: 14px;
            background: linear-gradient(90deg, #4CAF50, #45a049);
            border: none;
            border-radius: 12px;
            color: white;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
            margin-top: 10px;
            transition: transform 0.2s;
        }
        button:hover {
            transform: scale(1.02);
        }
        button:active {
            transform: scale(0.98);
        }
        .result-box {
            margin-top: 25px;
            padding: 20px;
            background: rgba(0, 0, 0, 0.4);
            border-radius: 12px;
            border-left: 5px solid #4CAF50;
            opacity: 0;
            transition: opacity 0.5s;
        }
        .result-box.show {
            opacity: 1;
        }
        .percentage {
            font-size: 42px;
            font-weight: 900;
            color: #ffd700;
        }
        .detail {
            color: #bbb;
            margin-top: 10px;
            font-size: 14px;
        }
        .note {
            margin-top: 20px;
            font-size: 12px;
            color: #aaa;
            text-align: left;
            line-height: 1.6;
            border-top: 1px dashed #666;
            padding-top: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>⚽ 背身拿球成功率</h1>
        <form id="calcForm">
            <div class="input-group">
                <label for="attempts">⏱️ 背身拿球总次数</label>
                <input type="number" id="attempts" name="attempts" min="0" placeholder="30" required>
            </div>
            <div class="input-group">
                <label for="success">✅ 成功转身/回做球次数</label>
                <input type="number" id="success" name="success" min="0" placeholder="22" required>
            </div>
            <div class="input-group">
                <label for="context">🏷️ 场景描述(可选)</label>
                <input type="text" id="context" placeholder="英超赛季 - 凯恩">
            </div>
            <button type="button" onclick="calculate()">📊 计算成功率</button>
        </form>
        <div class="result-box" id="resultBox">
            <div class="percentage" id="percentage">--%</div>
            <div class="detail" id="detail">等待计算...</div>
        </div>
        <div class="note">
            <strong>📌 定义说明:</strong><br>
            成功率 = (成功次数 ÷ 总尝试次数) × 100%<br>
            <span style="color: #ffd700;">及格线:60%</span> | <span style="color: #4CAF50;">优秀线:70%</span> | <span style="color: #ff6347;">顶级:75%+</span>
        </div>
    </div>
    <script>
        function calculate() {
            const attempts = parseFloat(document.getElementById('attempts').value);
            const success = parseFloat(document.getElementById('success').value);
            const context = document.getElementById('context').value || '球员数据';
            // 输入验证
            if (isNaN(attempts) || attempts <= 0) {
                alert('请输入有效的背身拿球总次数!');
                return;
            }
            if (isNaN(success) || success < 0 || success > attempts) {
                alert('成功次数必须介于 0 和总次数之间!');
                return;
            }
            const percentage = ((success / attempts) * 100).toFixed(1);
            // 评级
            let grade = '';
            if (percentage >= 75) grade = '🌟 世界级水准';
            else if (percentage >= 70) grade = '🏆 精英级别';
            else if (percentage >= 60) grade = '✅ 合格水平';
            else if (percentage >= 50) grade = '⚠️ 有待提升';
            else grade = '❌ 需大量训练';
            // 显示结果
            const box = document.getElementById('resultBox');
            document.getElementById('percentage').textContent = percentage + '%';
            document.getElementById('detail').innerHTML = 
                `${context}:<strong>${success}/${attempts}</strong> 次成功<br>评级:${grade}`;
            box.classList.add('show');
        }
    </script>
</body>
</html>

使用建议与说明

  1. 成功率”的定义

    • 在专业足球数据(如Wyscout)中,这个数据通常特指“Under Pressure”情况下的Forward Pass SuccessDuel Success
    • 真正的背身拿球成功不仅指你没丢球,还指你传球给队友的准确率(尤其是向前传球),你可以调整Python脚本中的outcome字段,将“成功”定义为“传球成功且方向向前”。
  2. 剔除干扰项

    • 补时阶段、垃圾时间的胜负已定比赛,球员的对抗强度会下降,这会影响数据公正性,建议在Python脚本中增加minute列过滤(只统计1-80分钟的数据)。
  3. 对手强度修正

    • 顶级的背身中锋(如凯恩)面对高位逼抢时成功率会低于面对低位防守,如果你有对手的pressure_level字段,可以进行加权计算。
  4. 可视化输出

    • 你可以在Python脚本中加上matplotlib来绘制柱状图,比较不同球员之间的差距。

你觉得这个脚本是否符合你的需求? 如果你有具体的数据文件(或数据格式),可以告诉我,我可以帮你调整成可以直接读取你数据的版本。

抱歉,评论功能暂时关闭!