Blog Details

Home本地球迷活动三、六大可视化与洞察

三、六大可视化与洞察

🧑 博主简介:曾任某智慧城市类企业算法总监,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)。

四、结论与业务建议

头部效应明显:Top3 俱乐部薪资 = 其余 17 队之和。小球队需在转会市场挖掘高性价比球员。

高龄溢价:30+ 球员如 Immobile、Dzeko 仍享高薪,但 35 岁后断崖;球队续约需警惕风险。

青年红利:U22 球员中位数仅 33 万欧,是"低买高卖"战略洼地。

外援结构:巴西/阿根廷/葡萄牙球员平均年薪 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的更多可能!

<--微信名片-->

Copyright © 2088 世界杯乒乓球决赛|世界杯战绩|上海亿嘉斯世界杯活力魔都站|igas-shanghai.com All Rights Reserved.
友情链接