python足球分析系统_python分析欧洲足球赛事

数据来源:kaggle数据准备

import pandas as pd

import matplotlib.pyplot as plt

import numpy as np

import scipy as sp

inpath=r'C:\Users\......\Football\football-events\events.csv'

events=pd.read_csv(inpath) #导入主数据

events.isnull().sum() #缺失值汇总情况

path2=r'C:\Users\......\Football\football-events\dictionary.txt'

encoding=pd.read_table(path2,delim_whitespace=False,names=('num','events')) #导入解释性文件。因为主文件中都是用数字代替类型的

将主文件和解释性文件都导入python中

查看数据基本信息:

event.columns #主文件列名

event.isnull.sum()#汇总缺失值的信息

#提取各解释性文件,源文件为txt格式

event_type=encoding[1:13]

event_type_2=encoding[14:18]

side=encoding[19:21]

shot_place=encoding[22:35]

shot_outcome=encoding[36:40]

location=encoding[41:60]

bodypart=encoding[61:64]

assist_method=encoding[65:70]

situition=encoding[71:75]

将解释性文件保存,取消各解释性文件中的索引

event_type.to_csv(r'C:\Users\......\Football\football-events\event_type1.csv',index=False)

event_type_2.to_csv(r'C:\Users\......\Football\football-events\event_type_2.csv',index=False,header=False)

side.to_csv(r'C:\Users\......\Football\football-events\side.csv',index=False)

shot_place.to_csv(r'C:\Users\......\Football\football-events\shot_place.csv',index=False)

shot_outcome.to_csv(r'C:\Users\......\Football\football-events\shot_outcome.csv',index=False)

location.to_csv(r'C:\Users\......\Football\football-events\location.csv',index=False)

bodypart.to_csv(r'C:\Users\......\Football\football-events\bodypart.csv',index=False)

assist_method.to_csv(r'C:\Users\......\Football\football-events\assist_method.csv',index=False)

situition.to_csv(r'C:\Users\......\Football\football-events\situition.csv',index=False)

到目前为止,对文件的处理工作基本完成。当然,你也可以将解释性文件导入到主文件中,程序如下(各人觉得没必要):

y=[]

def tidai(x):

if x==1:

y='right foot'

if x==2:

y="left foot"

else:

y="head"

return y

goal1['events']=goal['bodypart'].apply(tidai) #将bodypart这个解释性文件内容导入到主文件中

对进球情况进行分析

# 选取有进球的赛事

goal=events[events.is_goal==1]对进球随时间分布情况进行分析

goal.time.max() #可知进球的时间最大为100min,即做直方图时可采用划分100等分

plt.figure(figsize=(20,20)) #设置画布大小

plt.rc("xtick",labelsize=20) #设置x刻度的文字大小

plt.rc("ytick",labelsize=20) #设置y轴刻度文字大小

plt.hist(goal.time,bins=100,color='blue',width=1) #将进球时间作为x轴,bins划分等分,设置颜色以及宽度

plt.xlabel("TIME",fontsize=30) #设置x轴的的文字以及大小

plt.ylabel("goal counts",fontsize=30) #设置y轴的的文字以及大小

plt.title("goal counts vs time",fontsize=35) #设置图标的标题

plt.show()进球数 vs 时间

结论:可以看出,所有赛事中进球的时间分布,其中在90min左右进球最多,其次是45min左右。当然,也可使用程序查看时间

goal.groupby(by=['time'])['is_goal'].sum().sort_values(ascending=False).head()进球最多的时间分布(top5)主客队进球情况分析

通过解释文件side可以知道,主文件中1代表主队,2代表客队

plt.figure(figsize=(20,15))

plt.grid() #开启网格

plt.rc('xtick',labelsize=20)

plt.rc('ytick',labelsize=20)

plt.hist(goal[goal.side==1].time,bins=100,label="Home team",color='green',width=1) #主队进球情况

plt.hist(goal[goal.side==2].time,bins=100,label="Away team",width=1) #客队进球情况

plt.xlabel("Time",fontsize=25)

plt.ylabel("counts",fontsize=25)

plt.title("goal counts vs time by side",fontsize=30)

plt.legend(loc="upper left",fontsize=15) #设置图例文字大小以及位置

plt.show()

结论:主动进球情况明显好于客队,主场作战一般都比较厉害怎么样进球的

goal['bodypart']=goal['bodypart'].fillna(1) #发现goal文件中bodypart还有一个缺失值,因此进行填充

goal['bodypart']=goal['bodypart'].astype('int') #改变数据格式,这条没有用的

goal1=goal.copy()

plt.figure(figsize=(10,10))

labels=["Right Foot","Left Foot","Headers"]

data1=[goal1[goal1["bodypart"]==1].shape[0],goal1[goal1["bodypart"]==2].shape[0],goal1[goal1["bodypart"]==3].shape[0]]

# shape[0]是用来汇总行数,当然这里也可以用groupby

# data1=goal1.groupby(by=['bodypart'])['bodypart'].count()

colors=["cyan","grey","pink"]

plt.pie(data1,labels=labels,colors=colors,autopct='%1.1f%%',startangle=60)

plt.axis('equal')

plt.title("Percentage of bodyparts for goals",fontname="Times New Roman Bold",fontsize=14)

plt.show()

结论:右脚进球是最主要的进攻方式,左脚次之,投球最少

plt.figure(figsize=(15,10))

plt.hist(goal1[goal1["bodypart"]==1]["time"],width=1,bins=100,color="cyan",label="Right foot")

plt.hist(goal1[goal1["bodypart"]==2]["time"],width=1,bins=100,color="grey",label="Left foot")

plt.hist(goal1[goal1["bodypart"]==3]["time"],width=1,bins=100,color="pink",label="Headers")

plt.xlabel("Minutes",fontsize=20)

plt.ylabel("Number of goals",fontsize=20)

plt.legend(loc='upper left')

plt.title("Number of goals (by body parts) against Time during match",fontname="Times New Roman Bold",fontsize=20,fontweight="bold")

plt.show()

可以看出:各种进攻方式随时间变化的趋势在何种情况下进球的分析

plt.figure(figsize=(15,15))

size=[goal1[goal1.situation==1].shape[0],goal1[goal1.situation==2].shape[0],goal1[goal1.situation==3].shape[0],goal1[goal1.situation==4].shape[0]]

colors=['pink','purple','blue','green']

plt.pie(size,colors=colors,labels=list(situition['events']),autopct='%.1f%%',textprops={"fontsize":15})

plt.title('Percentage of each situation for goals',fontsize=25)

plt.axis('equal')

plt.show()

结论:运动战的进球是最多的,占比达到70.8%

plt.figure(figsize=(20,10))

plt.hist(goal1[goal1.situation==1].time,bins=100,width=1,color='pink',label='Open play')

plt.hist(goal1[goal1.situation==2].time,bins=100,width=1,color='purple',label='Set piece')

plt.hist(goal1[goal1.situation==3].time,bins=100,width=1,color='blue',label='Corner')

plt.hist(goal1[goal1.situation==4].time,bins=100,width=1,color='green',label='Free kick')

plt.xlabel("TIME",fontsize=25)

plt.ylabel("goal counts",fontsize=25)

plt.rc('xtick',labelsize=15)

plt.rc('ytick',labelsize=15)

plt.title('Percentage of each situation for goals',fontsize=25,fontweight='bold')

plt.legend(loc='upper left',fontsize=15)

plt.show()

结论:各种进球方式随时间的变化可以看出,运动战中的进球均远远高于其他进球方式在哪进球的分析

将进球的位置划分为5类,但在主文件中尽然划分为15处,因此要进行简单处理

goal1.location.fillna(goal1.location.median(),inplace=True) #对缺失值进行众数的填充

goal1.location.unique() #结果为array([ 9., 3., 13., 15., 10., 11., 19., 6., 7., 14., 12.,8., 17., 18., 16.])

#获取划分为5类的汇总情况

diff_angle_goals=goal1[goal1.location==6].shape[0]+goal1[goal1.location==7].shape[0]+goal1[goal1.location==8].shape[0];

longdistance=goal1[goal1.location==16].shape[0]+goal1[goal1.location==17].shape[0]+goal1[goal1.location==18].shape[0]

box_goal=goal1[goal1.location==3].shape[0]+goal1[goal1.location==9].shape[0]+goal1[goal1.location==11].shape[0]+goal1[goal1.location==15].shape[0]

close_range_goals=sum(goal1["location"]==10)+sum(goal1["location"]==12)+sum(goal1["location"]==13)

penalties=goal1[goal1.location==14].shape[0]

not_recorded=goal1[goal1.location==19].shape[0]

#绘图

data=[diff_angle_goals,longdistance,box_goal,close_range_goals,penalties,not_recorded]; #将数据组成一个list

label=['diff_angle_goals','longdistance','box_goal','close_range_goals','penalties','not_recorded']#图例

colors=["gray","yellow","aqua","coral","red","violet"] #颜色

distance=[0,0.,0.05,0,0.,0] #突出显示最大值

plt.figure(figsize=(15,15))

plt.pie(data,colors=colors,labels=label,autopct='%.2f%%',labeldistance=1,startangle=30,

explode=distance,textprops={'fontsize':13},radius=2)

plt.axis('equal')

plt.title("Percentage of each location for goals",fontsize=18,fontweight="bold")

plt.legend(fontsize=12)

plt.show()

结论:大部分得分都来自禁区(64.55%)和近距离射门(19.43%)助攻分布情况

goal1.groupby(by='assist_method')['time'].count() #各助攻情况的分布情况

list(assist_method.events)

plt.figure(figsize=(10,10))

plt.pie(goal1.groupby(by='assist_method')['time'].count(),labels=list(assist_method.events),autopct='%1.2f%%'

,textprops={'fontsize':15,'color':'black'})

plt.title("assist_method info",fontsize=20)

plt.axis('equal')

plt.show()

结论:超过32%的进球都是独自完成,没有通过助攻形式,35.43%是靠直接助攻而得分

对赛事中替换情况进行分析

有解释文件中可以看出,event_type为7的是有替换值的赛事

substitution=events[events.event_type==7] #获取替换的赛事

plt.figure(figsize=(20,13))

plt.rc('xtick',labelsize=15)

plt.rc('ytick',labelsize=15)

plt.plot(substitution.groupby(['time']).count(),color='red')

plt.hist(substitution.time,color='green',bins=100)

plt.xlabel("Time",fontsize=15)

plt.ylabel("substiution info",fontsize=15)

plt.title("substitution vs time",fontsize=20)

plt.grid()

plt.show()

substitution.groupby(by='time')['time'].count().sort_values(ascending=False).head()

可以看出,比赛中最常换人的是在45min左右,也就是下半场开场的时候。整体趋势来看,下半场是换人最多的时间段。

那么主客队的换人情况又是如何呢?

data=substitution.groupby(['side'])['side'].count() #按照主客队进行分组汇总

plt.pie(data,labels=['home side','away side'],autopct='%.3f%%',startangle=90)

plt.axis('equal')

plt.title("home side VS away side by substitution",fontsize=15)

plt.show()

主客队换人整体占比主客队换人随时间变化趋势

红黄牌趋势分析

很多人会说比赛过程中存在“主场哨”,事实是否如此呢?黄牌趋势

yellowcard=events[events.event_type==4] #黄牌情况信息

plt.figure(figsize=(10,8))

plt.hist(yellowcard.time,bins=10,color='yellow',width=5)

plt.title("yellow card distribution",fontsize=15)

plt.show()

你可能感兴趣的:(python足球分析系统)