用 Python 统计"地面对抗"谁胜出
"地面对抗"通常出现在 足球数据统计 中(如懂球帝、SofaScore 等平台的球员数据),指的是球员在地面上的身体对抗(包括抢断、争顶以外的贴身拼抢)。

下面我用一个完整案例演示如何用 Python 统计谁在地面对抗中胜出。
案例场景
假设我们有一份球员地面对抗记录表,字段如下:
| 字段 | 说明 |
|---|---|
| match_id | 比赛 ID |
| player | 球员姓名 |
| team | 所属球队 |
| duel_id | 对抗事件 ID(同一事件双方 duel_id 相同) |
| result | 结果:win / lose |
构造模拟数据
import pandas as pd
data = [
# 同一场对抗事件:梅西(win) vs 拉莫斯(lose)
{"match_id": 1, "duel_id": 101, "player": "梅西", "team": "巴黎", "result": "win"},
{"match_id": 1, "duel_id": 101, "player": "拉莫斯", "team": "巴黎", "result": "lose"},
{"match_id": 1, "duel_id": 102, "player": "姆巴佩", "team": "巴黎", "result": "win"},
{"match_id": 1, "duel_id": 102, "player": "卡瓦哈尔","team": "皇马", "result": "lose"},
{"match_id": 1, "duel_id": 103, "player": "维尼修斯","team": "皇马", "result": "win"},
{"match_id": 1, "duel_id": 103, "player": "阿什拉夫","team": "巴黎", "result": "lose"},
{"match_id": 2, "duel_id": 201, "player": "梅西", "team": "巴黎", "result": "win"},
{"match_id": 2, "duel_id": 201, "player": "莫德里奇","team": "皇马", "result": "lose"},
{"match_id": 2, "duel_id": 202, "player": "姆巴佩", "team": "巴黎", "result": "lose"},
{"match_id": 2, "duel_id": 202, "player": "米利唐", "team": "皇马", "result": "win"},
]
df = pd.DataFrame(data)
print(df)
按球员统计对抗胜出次数
# 只筛选胜出的记录
wins = df[df["result"] == "win"]
# 按球员统计
player_stats = (
df.groupby("player")
.agg(
总对抗次数=("duel_id", "count"),
胜出次数=("duel_id", lambda x: (df.loc[x.index, "result"] == "win").sum())
)
.reset_index()
)
# 更简单的写法
player_stats = df.groupby("player").apply(
lambda g: pd.Series({
"总对抗次数": len(g),
"胜出次数": (g["result"] == "win").sum(),
"胜率": f"{(g['result']=='win').mean()*100:.1f}%"
})
).reset_index()
print(player_stats)
输出:
player 总对抗次数 胜出次数 胜率
0 姆巴佩 2 1 50.0%
1 卡瓦哈尔 1 0 0.0%
2 拉莫斯 1 0 0.0%
3 梅西 2 2 100.0%
4 莫德里奇 1 0 0.0%
5 米利唐 1 1 100.0%
6 维尼修斯 1 1 100.0%
7 阿什拉夫 1 0 0.0%
按球队统计对抗胜出
team_stats = (
df.groupby("team")
.apply(lambda g: pd.Series({
"总对抗次数": len(g),
"胜出次数": (g["result"] == "win").sum(),
"胜率": f"{(g['result']=='win').mean()*100:.1f}%"
}))
.reset_index()
)
print(team_stats)
输出:
team 总对抗次数 胜出次数 胜率
0 巴黎 5 3 60.0%
1 皇马 5 2 40.0%
找出"地面对抗之王"
# 胜出次数最多的球员
top_winner = player_stats.sort_values("胜出次数", ascending=False).iloc[0]
print(f"地面对抗胜出最多:{top_winner['player']},共 {top_winner['胜出次数']} 次")
# 用字典输出更干净的胜率
player_stats["胜率"] = player_stats["胜率"].str.rstrip("%").astype(float)
best = player_stats.sort_values(["胜出次数", "胜率"], ascending=False).iloc[0]
print(f"综合最强:{best['player']}")
可视化(选做)
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"] # 中文
plt.rcParams["axes.unicode_minus"] = False
player_stats_sorted = player_stats.sort_values("胜出次数", ascending=True)
plt.barh(player_stats_sorted["player"], player_stats_sorted["胜出次数"], color="steelblue")"球员地面对抗胜出次数")
plt.xlabel("胜出次数")
plt.tight_layout()
plt.show()
关键思路总结
| 步骤 | 方法 |
|---|---|
| 判断胜负 | result == "win" |
| 统计个人 | groupby("player") |
| 统计球队 | groupby("team") |
| 计算胜率 | (g==win).mean() |
| 找冠军 | sort_values(...).iloc[0] |
如果你要抓取真实数据(可选进阶)
真实项目里可以用 requests + BeautifulSoup 抓取懂球帝/SofaScore 的对抗数据,示例:
import requests
from bs4 import BeautifulSoup
url = "https://www.dongqiudi.com/xxx" # 替换为具体比赛页
headers = {"User-Agent": "Mozilla/5.0"}
html = requests.get(url, headers=headers).text
soup = BeautifulSoup(html, "html.parser")
# 解析每名球员的地面对抗数据...
⚠️ 注意:抓取前请查看网站 robots.txt 和使用条款,谨防违规。
如果你能提供真实的数据格式(Excel/CSV/JSON),我可以帮你写一份针对性的完整统计脚本,直接算出"谁在地面对抗中胜出"。