1. 主页 > 世界杯新闻 >

数据分析用例一:足球运动员数据分析

一、示例分析

目的: 练习pandas模块的使用,数据清洗和数据分析

需求:

运动员的体重分布情况

足球使用左右脚的分析

俱乐部球员分析

运动员与出生日期是否相关

身高与体重相关性

年龄与评分相关性

环境: numpy,pandas,python

二、处理流程介绍

2.1、查看数据的基本情况

import pandas as pd

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

df.head()

# 设置默认显示的行数

pd.set_option('display.max_rows', 5)

# 设置默认显示的列数

pd.set_option('display.max_columns', 8)

# 查看数据

# 查看数据的形状

# df.shape

# 查看数据的前5行

# df.head()

# 查看数据的后5行

# df.tail()

# 随机查看数据的5行

df.sample(5)

数据详细

字段名备注Name姓名Nationality国籍National_Position国家队位置National_Kit国家队号码Club所在俱乐部Club_Position所在俱乐部位置Club_Kit俱乐部号码Club_Joining加入俱乐部时间Contract_Expiry合同到期时间Rating评分Height身高Weight体重Preffered_Foot擅长左(右)脚Birth_Date出生日期Age年龄Preffered_Position擅长位置Work_Rate工作效率Weak_foot非惯用脚使用频率Skill_Moves技术等级Ball_Control控球技术Dribbling盘球(带球)能力Marking盯人能力Sliding_Tackle铲球Standing_Tackle逼抢能力Aggression攻击能力Reactions反映Attacking_Position攻击性跑位Interceptions抢断Vision视野Composure镇静Crossing下底传中Short_Pass短传Long_Pass长传Acceleration加速度Speed速度Stamina体力Strength强壮Balance平衡Agility敏捷度Jumping跳跃Heading投球Shot_Power射门力量Finishing射门Long_Shots远射Curve弧线Freekick_Accuracy任意球精准度Penalties点球Volleys凌空能力GK_Positioning门将位置感GK_Diving扑救能力GK_Kicking门将踢球能力GK_Handling扑球脱手几率GK_Reflexes门将反应度# df.columns

df.columns = ["姓名","国籍","国家队位置","国家队号码","所在俱乐部","所在俱乐部位置","俱乐部号码","加入俱乐部时间","合同到期时间","评分","身高","体重","擅长左(右)脚","出生日期","年龄","擅长位置","工作效率","非惯用脚使用频率","技术等级","控球技术","盘球(带球)能力","盯人能力","铲球","逼抢能力","攻击能力","反映","攻击性跑位","抢断","视野","镇静","下底传中","短传","长传","加速度","速度","体力","强壮","平衡","敏捷度","跳跃","投球","射门力量","射门","远射","弧线","任意球精准度","点球","凌空能力","门将位置感","扑救能力","门将踢球能力","扑球脱手几率","门将反应度"]

2.2、缺值处理

查看数据的数据类型

df.info()

从上述示例可以看到总共17588行,但National_Position(国家队位置) 是1075行,Club_Position (俱乐部位置)17587行。我们知道有的足球运动员是没有进入国家队的,所以National_Position缺值是正常情况。但Club_Position缺值需要处理。

# 查看是否有缺失值

# df['所在俱乐部位置'].isnull().any()

# df['所在俱乐部位置'].isna().any()

# 显示缺失值的数据

# df[df['所在俱乐部位置'].isnull()]

# df[df['所在俱乐部位置'].isna()]

# 没有缺失值的数据

# df2 = df[~df['所在俱乐部位置'].isna()]

# df2 = df[df['所在俱乐部位置'].notna()]

df2 = df[df['所在俱乐部位置'].notnull()]

df2

2.3、异常值处理

describe方法得到数据的描述性统计信息,比如max min,mean,std进行异常值分析。

# 数据的描述性统计信息

# 模拟创造一个异常值

df2.loc[0,'评分'] = 888

df2['评分']

# 发现异常值

# 通过数据的描述性统计信息,查看最小值、最大值

df2.describe()

# 通过条件判断筛选

df2[df2['评分'] < 0]

df2[df2['评分'] > 100]

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif']=['SimHei'] #指定默认字体 SimHei为黑体

# 通过图形化的方式查看异常值 -- 使用箱线图辅助查看异常值

# df2.plot(kind='box')

# df2.boxplot(column='评分')

# 然后确认异常值的原因

# 获取评分 和盯人能力

df2[['盯人能力','评分']].plot(kind='box')

df2['盯人能力'].describe()

# 对数据进行修改

df2.loc()[0,'评分'] = 94

df2['评分']

2.4 、重复值处理

# 查看是否有重复数据

# df2.duplicated().any()

# 查看没有重复的数据

# df2[~df2.duplicated()]

# 删除重复的数据 默认所有列都重复才删除

# df2.drop_duplicates()

# 指定列重复才删除

# 查看是否有重复值,指定某列重复才算重复,使用subset参数

# df2.duplicated(subset=['姓名']).any()

# 获取重复值数据

# df2[df2.duplicated(subset=['姓名'])]

# 获取没有重复值的数据,通过数据筛选

# df2[~df2.duplicated(subset=['姓名'])]

# 删除重复值

df3 = df2.drop_duplicates(subset=['姓名'], inplace=True)

df3

# 原有的df2是替换数据

# df2.drop_duplicates(inplace=True)

2.5 、数据预处理 身高/体重

运动员身高和体重分布

从查看数据结果可以看到运动员身高Height、体重Weight的数据后都添加了相应的单位。要分析运动员身高和体重的分布,首先需要将身高Height和Weight数据的单位去掉。

# 去掉身高和体重的单位,通过字符串的替换

# df3['身高'] = df3['身高'].str.replace('cm','').astype('int')

# df3['体重'] = df3['体重'].str.replace('kg','').astype('int')

df3[['身高','体重']]

df3[['身高','体重']].info()

# # 通过apply方式

# def handle_cm(v:str) -> int:

# return int(v.replace('cm',''))

# df3['身高'] = df3['身高'].apply(handle_cm)

# # 使用匿名函数的方式 lambda

# df3['体重'] = df3['体重'].apply(lambda v:int(v.replace('kg','')))

2.6 、数据预处理 身高/体重/ 评分分布

# 1. 通过命令的方式 describe

# 查看数据的分布情况

# df3[['身高','体重']].describe()

# 2. 通过图形化的方式 直方图、密度图

# 画图的方式 matplotlib\ pandas

# 导入模块

import matplotlib.pyplot as plt

# 通过matplotlib画直方图

# plt.hist(df3['身高'],bins=15)

# # 通过pandas画直方图

# df3['身高'].hist(bins=15)

# df3['体重'].hist(bins=15)

# # pip install scipy==1.11.2

# # 通过pandas画密度图

df3['身高'].plot(kind='kde')

df3['体重'].plot(kind='kde')

2.7 、数据分析 分析左右脚使用习惯

#【示例】查看足球运动员左脚右脚使用情况

df['擅长左(右)脚'].head(10)

可以看到,足球运动员踢球有使用左脚也有使用右脚。要统计使用左脚和右脚的数量,需要按Preffered_Foot进行分组,计算其count()值。我们可以使用饼状图来显示左脚右脚选手数量的差别。

# 使用饼状图来显示左脚右脚选手数量的差别

# df3['擅长左(右)脚'].head(10)

g = df3.groupby('擅长左(右)脚')

s = g['擅长左(右)脚'].count()

s.plot(kind='pie',autopct='%.2f')

# value_counts()方法的使用

foot_counts = df3['擅长左(右)脚'].value_counts()

foot_counts.plot(kind='pie',autopct='%.2f')

# 使用条形图来显示左脚右脚选手数量的差别

# 上面的操作,其实就是针对擅长左(右)脚分组,再统计每组的数量

df3['擅长左(右)脚'].value_counts().plot(kind='barh', fontsize=15)

2.8、数据分析 俱乐部球员评分分析

从球员评分角度分析,拥有top10评分能力俱乐部。

# 获取评分前10的运动员

# df3[['姓名','评分']].sort_values(by='评分', ascending=False).head(10)

df3[['姓名','评分','所在俱乐部']].sort_values(by='评分',ascending=False).head(10)

# 获取前10的俱乐部,根据球员的评分

dfg1 = df3.groupby('所在俱乐部')

dfg1['评分'].mean().sort_values(ascending=False).head(10)

# 对俱乐部人数大于25人的俱乐部,平均评分进行排序取前10

# 查看俱乐部的球员的人数和球员的评分

rs1 = dfg1['评分'].agg(['mean','count'])

# 查看俱乐部的球员人数,球员的平均分,过滤掉人数小于25

# rs1['count'] >= 25

# 查看俱乐部的球员人数,球员的平均分,过滤掉人数小于25,排名前10的俱乐部

# rs1[rs1['count'] >= 25].sort_values(by='mean',ascending=False).head(10)

# 根据排名进行绘制图表

rs1[rs1['count'] >= 25].sort_values(by='mean',ascending=False).head(10).plot(kind='bar')

2.9、数据分析 足球运动员与出生日期的关系

# 获取足球运动员日期

# 获取出生日期

# df['出生日期']

# 切分

t = df['出生日期'].str.split('/',expand=True)

# t

# 对月份进行分析:根据月份来分组,统计每一个月对应的球员数量,最后柱状图表示

# t[0].value_counts(ascending=False).plot(kind='bar') # 月

# t[1].value_counts(ascending=False).plot(kind='bar') # 日

t[2].value_counts(ascending=False).plot(kind='bar') # 年

# 评分大于等于80的球员数据

result = df[df['评分'] > 80]

# result

t = result['出生日期'].str.split('/',expand=True)

# t

# 通过图表分析和月是否有关

# t[0].value_counts(ascending=False).plot(kind='bar')

# 通过图表分析和日是否有关

# t[1].value_counts(ascending=False).plot(kind='bar')

# 通过图表分析和年是否有关

t[2].value_counts(ascending=False).plot(kind='bar')

2.10、数据分析 身高与体重是否具有相关性

# 通过散点图查看变量之间的关系 身高和体重

# df3.plot(kind='scatter',x='身高',y='体重')

# 身高和评分之间的关系

# df3.plot(kind='scatter',x='身高',y='评分')

# 使用相关系数描述身高和体重之间的关系

# df3['身高'].corr(df3['体重'])

# df3['身高'].corr(df3['评分'])

df3[['身高','体重','评分']].corr()

# 与评分相关性强的指标有哪些

# 筛选和评分相关性的数据

# df3.select_dtypes(include=['number']).corr()

# df3.select_dtypes(include=['number']).corr()['评分']

# 筛选和评分相关性的数据,比较强的前10个指标

# select_dtypes(include=['number'])指定选择的数据类型为整型的才进行整理和处理

df3.select_dtypes(include=['number']).corr()['评分'].sort_values(ascending=False).head(10)

2.11、数据分析 探索分析数据之间的相关性

# 年龄与评分是否相关

# 查看评分和年龄的相关性

# df3.plot.scatter(x='年龄',y='评分')

# 对年龄进行分组

# pd.cut(df3['年龄'],bins=4,labels=['青年','中年','壮年','老年'])

# 将切分好的数据,添加到原来的数据中

df3['age'] = pd.cut(df3['年龄'],bins=4,labels=['青年','中年','壮年','老年'])

# # 按照年龄分组,查看评分的情况

# df3.groupby('age')['评分'].mean()

# # 通过图表,按照年龄分组,查看评分的情况

df3.groupby('age')['评分'].mean().plot(kind='line')

# 按照年龄分组,指定分组的边界

pd.cut(df3['年龄'],bins=[10,30,40,50],labels=['青年','中年','壮年'])