奥运会自1896年开始,每4年举办一次,从1904年起,夏季奥运会的每个项目都会颁发奖牌。夏季奥运会取得的成功促使了冬季奥林匹克运动会的产生。
本案例的目的在于通过一个实际的奥运会运动员数据集,让大家快速掌握数据可视化的基本操作,熟悉使用Python进行简单数据处理的过程,为之后的机器学习建模做好铺垫。
列名 | 含义 |
---|---|
ID | 编号 |
Name | 名字 |
Sex | 性别 |
Age | 年龄 |
Height | 身高 |
Weight | 体重 |
Team | 队伍 |
NOC | 国家/地区代号 |
Games | 奥运会名称 |
Year | 时间 |
Season | 季节 |
City | 城市 |
Sport | 运动大类 |
Event | 具体运动项目 |
Medal | 奖牌 |
import pandas as pd
import numpy as np
import matplotlib.font_manager as fm
myfont = fm.FontProperties(fname='./input/simhei.ttf') ## 加入中文字体
athlete = pd.read_csv('./input/athlete_events.csv') ##导入数据
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all' ##显示cell中的所有结果
athlete.shape
athlete.columns
athlete.isnull().any() ##检查数据集中每列是否有缺失值(any和all)
### 填补缺失值
athlete['Height'] = athlete['Height'].fillna(athlete['Height'].mean())
athlete['Weight'] = athlete['Weight'].fillna(athlete['Weight'].mean())
athlete = athlete[athlete['Age'].notnull()]
athlete['Medal'] = athlete['Medal'].fillna('NoMedal')
athlete.isnull().any() ##再次验证
## 常用的工具
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
第一步:创建画布(子图)
plot1=plt.figure(figsize=(8,6),dpi=144) #设置大小和清晰度
第二步:画布内容
plt.title('标题') #添加标题
plt.xlabel('x') #添加x轴的名称
plt.ylabel('y') #添加y轴的名称
plt.xlim((0,1)) #x轴刻度范围
plt.ylim((0,1)) #y轴刻度范围
plt.xticks([0,1,2,3,4]) #x轴的刻度值
plt.yticks([0,1,2,3,4]) #y轴的刻度值
第三步:开始绘图
## 1、Matplotlib-散点图(一般用于连续性数据)
athlete.columns
plt.figure(figsize=(8,6))
plt.scatter(x=athlete['Height'],y=athlete['Weight'])
plt.title('身高和体重的散点图',fontproperties=myfont) #添加标题
plt.xlabel('身高',fontproperties=myfont) #添加x轴的名称
plt.ylabel('体重',fontproperties=myfont) #添加y轴的名称
## 2、Matplotlib-折线图(属性值的变化趋势)
plt.figure(figsize=(8,6))
plt.plot(athlete['Age'][0:10])
plt.title('年龄的折线图',fontproperties=myfont,size=20) #添加标题
plt.ylabel('年龄',fontproperties=myfont,size=20) #添加y轴的名称
## 3、Matplotlib-直方图(表示属性值在某区间的数量)
plt.figure(figsize=(8,6))
plt.hist(athlete['Age']) ##垂直:vertical
plt.title('年龄的条形图',fontproperties=myfont,size=20) #添加标题
plt.xlabel('年龄',fontproperties=myfont,size=20) #添加x轴的名称
plt.ylabel('数量',fontproperties=myfont,size=20) #添加y轴的名称
## 4、Matplotlib-箱线图(检测异常值)
plt.figure(figsize=(8,6))
plt.boxplot(athlete['Weight']) ##垂直:vertical
plt.title('体重的箱线图',fontproperties=myfont,size=20) #添加标题
plt.xlabel('体重',fontproperties=myfont,size=20) #添加x轴的名称
## 7、Seaborn——散点图(配色更好看,种类更多但函数和操作比较简单)
plt.figure(figsize=(30,20))
sns.jointplot(x=athlete['Height'],y=athlete['Weight'],kind='reg')
## 8、Seaborn——箱线图
plt.figure(figsize=(30,20))
plot8=sns.boxplot(x='Sex',y='Weight',data=athlete)
## 金银铜牌合并为得奖
pd.options.mode.chained_assignment = None
athlete.Medal[(athlete['Medal']!='NoMedal')]= 'Medal'
athlete.head()
medals = athlete[athlete['Medal'] == 'Medal'] ##将得奖的分离出来
medals.head()
plt.figure(figsize=(30, 10)) ##设置图片大小
sns.countplot(medals['Age']) ##选择图表类型
plt.title('奖牌随年龄的分布', fontproperties=myfont,size=20) ##设置标题
plt.figure(figsize=(20, 10))
sns.countplot(medals.Sport[medals['Age'] > 50])
plt.title('年龄大于50的得奖数',fontproperties=myfont,size=20)
## 射击、马术、航海、赛艇、美术比赛、爬山、 射箭、冰壶、槌球、击剑
country=(medals.Team[medals['Age'] > 50]).value_counts()
plt.figure(figsize=(20, 10))
sns.barplot(x=country.index[0:9],y=country.values[0:9])
#sns.countplot(medals.Team[medals['Age'] > 50])
plt.title('年龄大于50的得奖数(前10名)',fontproperties=myfont,size=20)
plt.figure(figsize=(20, 10))
sns.countplot(x='Year', data=medals, hue='Sex')
plt.title('得奖数随年龄的变化 ',fontproperties=myfont,size=20)
## 直观观察,计算比率
#gender = medals.pivot_table(medals, index=['Year'],columns='Sex')
#gender
#gender = medals.pivot_table(medals, index=['Year'], columns='Sex', aggfunc=len) ## len为统计个数
gender = medals.pivot_table(medals, index=['Year','Games'], columns='Sex', aggfunc=len).reset_index()[['Year','Games','Sport']]
gender
gender.columns = ['Year','Games','F','M']
gender.fillna(0,inplace=True)
gender
gender['ratio'] = gender['F'] /(gender['F'] + gender['M'])
def data(a):
if a==0:
a=0
elif 0<a<=0.15:
a=0.15
elif 0.15<a<=0.3:
a=0.3
else:
a=0.45
return a
gender.ratio=gender.ratio.apply(data)
gender
plt.figure(figsize=(30,20))
plt.scatter(gender['M'],gender['F'],s=300)
plt.xlabel('M',size=20)
plt.ylabel('F',size=20)
plt.title('男性与女性得奖数的对比', fontproperties=myfont,size=24)
country = medals.Team.value_counts().reset_index(name='medal').head(10)
country
plt.figure(figsize=(30, 10)) ##一定要在开头设置
country_plot = sns.barplot(x='index', y='medal', data=country)
country_plot.set_xlabel("top 10 countries")
country_plot.set_ylabel("numbers of medals")
plt.title('国家的得奖数',fontproperties=myfont,size=20)
team = medals.pivot_table(medals, index=['Year','Team'], aggfunc=len).reset_index()[['Year','Team','Sport']]
us=team[team['Team']=='United States']
su=team[team['Team']=='Soviet Union']
germany=team[team['Team']=='Germany']
britain=team[team['Team']=='Great Britain']
italy=team[team['Team']=='Italy']
team
plt.figure(figsize=(30, 10))
plt.title('Comparision between top5 countries in years')
plt.plot(us.Year, us.Sport, color='green', label='USA medals')
plt.plot(su.Year, su.Sport, color='red', label='SU medals')
plt.plot(germany.Year, germany.Sport, color='skyblue', label='Germant medals')
plt.plot( britain.Year, britain.Sport, color='blue', label='Britain medals')
plt.plot(italy.Year, italy.Sport, color='blue', label='Italy medals')
plt.legend() # 显示图例
plt.xlabel('Year')
plt.ylabel('Medal_counts')
team2=pd.concat([us,su,germany,britain,italy],axis=0)
team2
g=sns.FacetGrid(team2,col='Team')
g.map(plt.plot,'Year','Sport')