本文分两部分:
1.描述分析部分,着重进行数据的可视化分析,图片使用Python绘图包matplotlib生成,使用ppt制作为图文形式方便阅读,图片生成代码和分析过程代码在第二部分呈现;
2.具体操作部分,呈现完整的数据分析流程和全部代码。
描述分析报告
2.具体操作和代码呈现
数据理解项目说明
数据内容说明
提出问题
理解数据
数据清洗检查缺失值
检查并处理异常值
分析数据整体观察
逐项展示
项目说明
数据来源于CSDN,碰巧看到我感兴趣的数据于是便下载来分析,利用pandas包导入数据再用matplotlib包对数据进行可视化处理。让读者直观感受历届世界杯概况。https://download.csdn.net/download/willty/10490897download.csdn.net
数据内容说明数据是从1930年第一届世界杯开始到2014年,没有2018的数据。所以只截止到2014年。
世界杯历史上有2次决赛是平局用点球大战决胜负的,但是数据没记录点球
大战的成绩于是我手动添加点球大战的比分进正常时间的比分里面了。
有些国家前后名字有变动如苏联,就没有去更改。德国以前叫Germany FR就改成了现在的Germany。
由于1938-1950间正值一,二战时期1942,1946年世界杯取消。
提出问题主队和客队那个胜率更高,主场优势是否存在。
观众对于世界杯的热情发展趋势如何。
足球强国那么多到底哪个国家才是世界杯大热门。
理解数据
Year: 年份Datetime: 日期
Stage: 比赛类别(小组赛,决赛等)
Stadium: 场馆
Home Team Name: 主队名
Home Team Goals: 主队得分
Away Team Name: 客队名
Away Team Goals: 客队得分
Attendance: 观众数量
Half-timeHomeGoals: 主队上半场进球
Half-timeAwayGoals: 客队上半场进球
Referee: 主裁名字和国籍
Assistant 1: 边裁1名字和国籍
Assistant 2: 边裁2名字和国籍
RoundID: 轮次ID
MatchID: 赛事ID
Home Team Initials: 主队简称
Away Team Initials: 客队简称
数据清洗
导入数据:
import pandas as pd
xls=pd.ExcelFile('D:\\WorldCupMatches.xlsx')
Matches=xls.parse('WorldCupMatches')
Matches.head()
Matches.drop_duplicates(subset=['MatchID'],keep='first',inplace=True)
Matches.info()
由于赛事ID唯一所以删除重复值,最后得到836行的数据。
Matches['Attendance']=Matches['Attendance'].fillna(int(Matches['Attendance'].mean()))
由于观众人数缺失了一个数据,我用fillna函数对其填入了观众的平均值
i=0
w=0
p=0
l=0
while i<836:
if Matches['Home Team Goals'][i]>Matches['Away Team Goals'][i]:
w=w+1
elif Matches['Home Team Goals'][i]==Matches['Away Team Goals'][i]:
p=p+1
else:
l=l+1
i+=1
print(w)
print(p)
print(l)
data=[w,p,l]
使用while循环遍历数据统计出主客队得分来判断胜负情况
import matplotlib.pyplot as plt
plt.figure('Subplot', facecolor='lightgray',dpi=150)
plt.subplot(221)
x=range(len(data))
y=data
plt.title('主客场胜场数',fontsize=8)
plt.xlabel('对局',fontsize=8)
plt.ylabel('胜场数',fontsize=8)
plt.ylim((0,700))
plt.grid(axis='y', linestyle=':')
name_list=['主场胜','平局','客场胜']
plt.bar(x, y, 0.5,fc='g',alpha=0.5,tick_label=name_list,label='Sapltle 1')
for _x, _y in zip(x, y):
plt.text(_x, _y, _y,ha='center', va='bottom', size=8)
plt.legend()
plt.subplot(222)
lables = ['主队','客队']
plt.title('主客场胜场得分箱线图',fontsize=8)
plt.xlabel('队伍',fontsize=8)
plt.ylabel('得分',fontsize=8)
plt.boxplot([Matches['Home Team Goals'],Matches['Away Team Goals']],sym='o',whis=1.5,labels=lables)
plt.grid(axis='y', linestyle=':')
plt.tight_layout()
plt.show()
figure函数定义画板样式(背景颜色,大小)
subplot函数可以设定有多少个子图
grid可以制作网格
从以上可以看出:主场球队获胜概率远大于客场队
主队进球的平均水平从箱线图看来整体也高于客队
groupbyyearDf=Matches.groupby('Year').sum()
groupbyyearDf=groupbyyearDf.reset_index()
groupbyyearDf.head()
使用groupby函数队特定的行名可以分组,但是groubby之后索引就变成行名了所以要用.reset_index()函数重新排序。然后就可以做统计了。
x=groupbyyearDf['Year']
y=groupbyyearDf['Attendance']/10000
plt.figure('bar',facecolor='lightgray',dpi=120)
plt.title('观众总数')
plt.xlabel('年份')
plt.ylabel('观众人数(万)')
plt.grid(axis='y',linestyle=':')
plt.xticks(groupbyyearDf['Year'],rotation=45)
plt.plot(x,y,color='r')
plt.show()
统计了世界杯开始到14年观众的总数得出结论:民众对于世界杯的热情呈明显上升趋势
1994年美国世界观众数量历史最高
GoalsDf=pd.DataFrame()
GoalsDf['GoalsHalf']=groupbyyearDf['Half-time Home Goals']+groupbyyearDf['Half-time Away Goals']
GoalsDf['GoalsHalf2']=groupbyyearDf['Home Team Goals']+groupbyyearDf['Away Team Goals']-GoalsDf['GoalsHalf']
x=groupbyyearDf['Year']
y1=GoalsDf['GoalsHalf2']
y2=GoalsDf['GoalsHalf']
plt.figure('bar',facecolor='Lightgray',dpi=120)
plt.xticks(groupbyyearDf['Year'],rotation=45)
plt.grid(axis='y',linestyle=':')
plt.bar(x,y2,2,label='上半场')
plt.bar(x,y1,2,bottom=y2,label='下半场')
plt.xlabel('年份',fontsize=15)
plt.ylabel('总得分',fontsize=15)
plt.title('历届得分统计',fontsize=15)
plt.legend()
plt.show()
分组计算出了上下半场的得分情况,然后使用堆叠柱状图展示。得到以下结论:二战后的2届世界杯进球数量同比增多了不少,应该是热情更高涨了。
近代02-10年球队疲软了进球数量和80年代差不多
下半场进球数量的比例明显高于上半场
#计算总进球数量
def score(name):
score1=Matches[(Matches['Home Team Name']==name)]['Home Team Goals']
score2=Matches[(Matches['Away Team Name']==name)]['Away Team Goals']
sumscore=sum(score1)+sum(score2)
return sumscore
sumScore=sum(Matches['Home Team Goals'])+sum(Matches['Away Team Goals'])
sumScore
计算出了进球总数sumScore=2390
ScoreHomeDf=pd.DataFrame()
ScoreHomeDf['Score']=Matches['Home Team Name'].map(score)
ScoreHomeDf['name']=Matches['Home Team Name']
ScoreHomeDf['pre']=ScoreHomeDf['Score']/sumScore
ScoreHomeDf.drop_duplicates(subset=['name'],inplace=True)
ScoreHomeDf=ScoreHomeDf.sort_values('Score', ascending=False)
randDf=pd.DataFrame()
randDf=ScoreHomeDf.head(10)
randDf
统计得出下表,筛选进球数前10国家。列分别为进球总数,国家名,进球量所占比例
import matplotlib.pyplot as plt
plt.figure('Subplot', facecolor='lightgray',figsize=(6, 5),dpi=150)
plt.subplot(221)
x=randDf['name']
y=randDf['Score']
plt.bar(x, y,fc='g',alpha=0.5)
plt.title('国家得分排名',fontsize=6)
plt.grid(axis='y',linestyle=':')
for _x,_y in zip(x,y):
plt.text(_x,_y,_y,ha='center',va='bottom',size=8)
plt.ylim(0,300)
plt.ylabel('得分',fontsize=5)
plt.xticks(rotation=45,fontsize=5)
plt.yticks(fontsize=5)
plt.subplot(222)
x=AppearanceDf['index']
y=AppearanceDf['count']
plt.grid(axis='y',linestyle=':')
plt.bar(x, y,fc='g',alpha=0.5)
plt.ylim(0,150)
plt.title('国家出场频率',fontsize=6)
plt.ylabel('得分',fontsize=5)
for _x,_y in zip(x,y):
plt.text(_x,_y,_y,ha='center',va='bottom',size=8)
plt.xticks(rotation=45,fontsize=5)
plt.yticks(fontsize=5)
plt.subplot(223)
x=AttenCountryDf['Conutry']
y=AttenCountryDf['Atten']/10000
plt.title('每个国家队观众数量(万)',fontsize=8)
plt.ylabel('观众数量',fontsize=5)
plt.grid(axis='y',linestyle=':')
plt.ylim(0,700)
for _x, _y in zip(x, y):
plt.text(_x, _y, '%.2f' % _y,ha='center',va='bottom', size=6)
plt.bar(x,y,color='g',alpha=0.5)
plt.xticks(rotation=45,fontsize=5)
plt.yticks(fontsize=5)
plt.subplot(224)
x=wincountDf['winner']
y=wincountDf['wincount']
plt.title('世界杯冠军次数',fontsize=6)
plt.ylabel('次数',fontsize=5)
plt.grid(axis='y',linestyle=':')
plt.bar(x,y,color='g')
plt.xticks(rotation=45,fontsize=5)
plt.yticks(fontsize=5)
plt.tight_layout()
plt.show
分析个国家得分情况,出场频率,观众数量,获得世界杯冠军次数。
得出结论:巴西德国意大利是世界杯三大热门球队,各项指标都是排前3的(但18年法国赢了世界杯冠军和意大利并列)
世界前10国家进球数打进了约世界杯一半的球。
共有11支队伍打入世界杯决赛,8支队伍获得过冠军
matplotlib小结:
按由大到小排列
画板figurefacecolor='色值' 背景颜色,色值可以随意设置但是一般用Lightgray好看一些
figsize=(x, y)设置长宽
dpi=xx 设置画板大小
subplot绘制子图subplot(x,y,z),x,y代表绘制x行,y列个子图,z代表第几个子图
subplot绘制子图
tight_layout()调整图表间距减少堆叠
figure,subplot实例:
import matplotlib.pyplot as plt
plt.figure('Subplot', facecolor='lightgray')
plt.subplot(231)
plt.text(0.5, 0.5, '1', ha='center', va='center', size=36, alpha=0.5)
plt.subplot(232)
plt.xticks(())
plt.yticks(())
plt.text(0.5, 0.5, '2', ha='center', va='center', size=36, alpha=0.5)
plt.subplot(233,facecolor = "red")
plt.xticks(())
plt.yticks(())
plt.text(0.5, 0.5, '3', ha='center', va='center', size=36, alpha=0.5)
plt.subplot(234)
plt.xticks(())
plt.yticks(())
plt.text(0.5, 0.5, '4', ha='center', va='center', size=36, alpha=0.5)
plt.subplot(235)
plt.xticks(())
plt.yticks(())
plt.text(0.5, 0.5, '5', ha='center', va='center', size=36, alpha=0.5)
plt.subplot(236)
plt.xticks(())
plt.yticks(())
plt.text(0.5, 0.5, '6', ha='center', va='center', size=36, alpha=0.5)
# tight_layout 调整子图之间的间隔来减少堆叠
plt.tight_layout()
plt.show()
图表类型:bar:柱状图
plot:折线图
scatter:散点图
pie:饼图
boxplot:箱线图
其余标记
title:图表标题
xlabel:x轴标题,y轴同理
xlim:x轴最大刻度,y轴同理
xticks;x轴刻度可以设置旋转角度,y轴同理
gird:网格线
可以使用for循环获取数值的坐标来做表格数据的标记:
for _x,_y in zip(x,y):
plt.text(_x,_y,_y,ha='center',va='bottom',size=8)