【数据可视化】2024-25 土耳其超级联赛薪资全景图:Python + PyEcharts 多维可视化实战

🧑 博主简介:曾任某智慧城市类企业算法总监,CSDN / 稀土掘金 等平台人工智能领域优质创作者。
目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。


一、引言

本文基于 2024-25 赛季 400+ 名土超球员的薪资明细(CSV 文件 turkish_superleague_salaries.csv),使用 Python + PyEcharts 从俱乐部、位置、年龄、国籍、合同年限、薪资结构六大维度做可视化与洞察。所有代码均可直接复制运行,生成交互式 HTML 报告,助你快速完成职场/课堂数据分析需求。


一、技术栈与数据说明

• 工具:Python 3.9、Pandas 1.5、PyEcharts 2.0

• 核心字段:Gross P/Y(年薪)、Pos.、Club、Age、Country、Years Remaining

• 预处理:

-- 去掉"€"和千位分隔符,转 float

-- 缺失年薪的三条记录(Saint-Maximin、Zaha、Mimovic)用 NaN 标记,不参与金额类可视化

-- 将 Pos. Detail 映射为 6 大类别:GK、DF、MF、FW、AM、DM


二、数据准备

python 复制代码
import pandas as pd, numpy as np, pyecharts.options as opts
from pyecharts.charts import Bar, Pie, Scatter, WordCloud, HeatMap, Line, Boxplot
from pyecharts.commons.utils import JsCode

df = pd.read_csv('turkish_superleague_salaries.csv')

# 1. 金额清洗
df['Gross_P_Y_EUR'] = (
    df['Gross P/Y (EUR)']
    .str.replace('€', '', regex=False)
    .str.replace(',', '', regex=False)
    .astype(float)
)

# 2. 位置合并
pos_map = {'GK': ['GK'], 'DF': ['CB', 'LB', 'RB'],
           'MF': ['CM', 'DM'], 'AM': ['AM', 'RW', 'LW', 'SS'],
           'FW': ['CF']}
def map_pos(x):
    for k, v in pos_map.items():
        if x in v:
            return k
    return 'Other'
df['Pos_simple'] = df['Pos. Detail'].apply(map_pos)

# 3. 年龄分段
df['Age_group'] = pd.cut(df['Age'], bins=[0, 22, 26, 30, 35, 100],
                         labels=['U22', '22-26', '27-30', '31-35', '35+'])

三、六大可视化与洞察

(以下代码块均可独立运行,生成 .html 文件,浏览器直接打开查看交互)

1. 俱乐部薪资 TOP10(Bar + 自定义渐变)

python 复制代码
top_club = (df.groupby('Club')['Gross_P_Y_EUR']
              .agg(total='sum', avg='mean', count='size')
              .sort_values('total', ascending=False)
              .head(10))

bar = (
    Bar()
    .add_xaxis(top_club.index.tolist())
    .add_yaxis("年薪总额(€)", [int(v) for v in top_club['total']])
    .set_series_opts(itemstyle_opts=opts.ItemStyleOpts(
        color=JsCode("new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:'#ff7f50'},{offset:1,color:'#1e90ff'}])")))
    .set_global_opts(title_opts=opts.TitleOpts(title="俱乐部薪资 TOP10"))
)
bar.render('club_salary_top10.html')

洞察:Fenerbahce、Galatasaray、Besiktas 三强合计占全联盟 55% 薪资池;第四名差距断崖。

2. 位置薪资箱线图

python 复制代码
pos_box = [df[df['Pos_simple']==p]['Gross_P_Y_EUR'].dropna().tolist() 
           for p in ['GK','DF','MF','AM','FW']]
box = Boxplot().add_xaxis(['GK','DF','MF','AM','FW']) \
               .add_yaxis("", Boxplot.prepare_data(pos_box)) \
               .set_global_opts(title_opts=opts.TitleOpts("不同位置年薪分布"))
box.render('position_box.html')

洞察:前锋(FW)与进攻型中场(AM)中位数显著高于后卫与门将,但波动极大;门将薪资最集中。

3. 年龄 vs 薪资 气泡图

python 复制代码
scatter = (Scatter().add_xaxis(xaxis_data=df['Age'].tolist())\
    .add_yaxis("",df['Gross_P_Y_EUR'].tolist(),color="#33FF00")\
    .set_series_opts()\
    .set_global_opts(
        #x轴配置
        xaxis_opts=opts.AxisOpts(
            name ="年龄",
            name_location = 'center',
            name_gap = 15,
            # 坐标轴类型 'value': 数值轴
            type_="value", 
            # 分割线配置项
            splitline_opts=opts.SplitLineOpts(is_show=True) #显示分割线
        ),
        #y轴配置
        yaxis_opts=opts.AxisOpts(
            name ="年薪(€)",
            # 坐标轴类型 'value': 数值轴
            type_="value",
            # 坐标轴刻度配置项
            axistick_opts=opts.AxisTickOpts(is_show=True),#显示刻度
            # 分割线配置项
            splitline_opts=opts.SplitLineOpts(is_show=True),#显示分割线
        ),
        # 提示框配置项
        tooltip_opts=opts.TooltipOpts(is_show=False), # 不显示提示框组件
    )
)
scatter.render('age_salary.html')

洞察:29-31 岁是薪资高峰,35 岁后骤降;极少数 20 岁出头新星拿到 300 万欧以上。

4. 国籍词云(仅年薪>1M)

python 复制代码
from pyecharts.charts import WordCloud
country_money = (df[df['Gross_P_Y_EUR'] > 1_000_000]
                 .groupby('Country')['Gross_P_Y_EUR'].sum())
wc = WordCloud().add("", list(zip(country_money.index, country_money.values)),
                     word_size_range=[15, 80])
wc.render('country_wordcloud.html')

洞察:巴西、阿根廷、葡萄牙占据外援高薪三大帮;土耳其本土球员更多集中在中低薪区。

5. 合同年限热力图(俱乐部 × 年限)

python 复制代码
hm = (df.groupby(['Club','Years Remaining']).size().unstack(fill_value=0))
x_axis, y_axis = hm.columns.astype(str).tolist(), hm.index.tolist()
value = [[i, j, int(hm.iloc[j, i])] for i in range(len(x_axis)) for j in range(len(y_axis))]
hm = (HeatMap().add_xaxis(x_axis).add_yaxis("", y_axis, value) \
         .set_global_opts(title_opts=opts.TitleOpts("俱乐部合同年限分布")))
hm.render('Club_year_emaining.html')

洞察:Fenerbahce、Galatasaray 大量 3-5 年长约锁定核心;小俱乐部 1 年短约为主,转会市场更灵活。

6. 年薪结构瀑布图(分位数区间)

python 复制代码
bins = [0, 0.5e6, 1e6, 2e6, 5e6, 10e6, 50e6]
labels = ['<0.5M', '0.5-1M', '1-2M', '2-5M', '5-10M', '>10M']
df['salary_band'] = pd.cut(df['Gross_P_Y_EUR'], bins=bins, labels=labels)
pie = Pie().add("", df['salary_band'].value_counts().items()) \
           .set_global_opts(title_opts=opts.TitleOpts("年薪分布区间")) \
           .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)"))
pie.render('salary_band_pie.html')

洞察:70% 球员年薪低于 100 万欧;>1000 万欧的"顶薪俱乐部"仅 6 人(Rafa Silva、Osimhen、Immobile、Icardi、Tadic、Fred)。


四、结论与业务建议

  1. 头部效应明显:Top3 俱乐部薪资 = 其余 17 队之和。小球队需在转会市场挖掘高性价比球员。
  2. 高龄溢价:30+ 球员如 Immobile、Dzeko 仍享高薪,但 35 岁后断崖;球队续约需警惕风险。
  3. 青年红利:U22 球员中位数仅 33 万欧,是"低买高卖"战略洼地。
  4. 外援结构:巴西/阿根廷/葡萄牙球员平均年薪 2.7× 本土球员,需平衡工资帽与战力。

五、一键生成综合仪表板

使用 Page 将所有图表串成单页报告:

python 复制代码
from pyecharts.charts import Page
page = Page(layout=Page.SimplePageLayout)
for chart in [bar, box, scatter, wc, hm, pie]:
    page.add(chart)
page.render('turkish_super_league_2024_salary_report.html')

浏览器打开 turkish_super_league_2024_salary_report.html,即可交互式查看全部洞察。


如果您在人工智能领域遇到技术难题,或是需要专业支持,无论是技术咨询、项目开发还是个性化解决方案,我都可以为您提供专业服务,如有需要可站内私信或添加下方VX名片(ID:xf982831907)

期待与您一起交流,共同探索AI的更多可能!

<--微信名片-->

相关推荐
云天徽上15 小时前
【数据可视化】2025 年欧足联排名数据可视化分析:Python + PyEcharts 多维可视化实战
数据可视化
云天徽上15 小时前
【数据可视化】2023 年 Spotify 歌曲数据集可视化分析
数据可视化
爱分享的飘哥2 天前
第十九篇 自动化报表生成:Python一键生成可视化Excel图表与专业PDF报告,老板看了都点赞!
自动化·办公自动化·数据可视化·excel自动化·python报表·pdf报告
银之夏雪丶2 天前
AntV G6 基础元素详解(React版)
前端·javascript·数据可视化
大数据魔法师2 天前
Matplotlib(一)- 数据可视化与Matplotlib
matplotlib·数据可视化
李昊哲小课5 天前
销售数据可视化分析项目
python·信息可视化·数据分析·matplotlib·数据可视化·seaborn
bug攻城狮7 天前
Alloy VS Promtail:基于 Loki 的日志采集架构对比与选型指南
运维·架构·grafana·数据可视化
今禾8 天前
" 当Base64遇上Blob,图像转换不再神秘,让你的网页瞬间变身魔法画布! "
前端·数据可视化
JIAKSK9 天前
VitePress 接入百度统计:全面教程与优化指南
运维·数据可视化