2018年"華爲杯"數學建模獲獎名單挖掘分析

本文針對2018年"華爲杯"數學建模6張擬獲獎名單做一次簡單的統計分析,以下分析結果僅代表思路,勿要以假亂真,權威結果統計以各大高校官方結果爲準。以該2018年"華爲杯"A,B,C,D,E,F共計6道題目的擬獲獎名單爲原材料。主要鍛鍊Python數據處理中的以下功能點的使用:
功能點:

1.把6張擬獲獎名單進行拼接
··· 1.1.1.將6張表橫向拼接;
··· 1.1.2.將6張表縱向拼接(後續處理主要使用按豎直方向拼接);
··· 1.1.3.簡單的檢索功能;
··· ··· ··· input:傳入自己學校的名稱即可整理出本校的參賽情況
··· ··· ···output:該校的參賽情況整合表
完成1中的處理針對單個高校信息的抽取已經可以完成,並在Excel表格中可以很容易的做出篩選和排序,並計算各個學校總的獲獎率和每道題目對應的獲獎率等等。但是要實現對全國參賽的上百組高校隊伍的批量分析和統計,設計詳細的數據結構存儲數據是必須的。第二部分將實現對全國參賽的上百組高校隊伍的參賽和獲獎情況的批量分析和統計。
2.抽取參賽高校列表
3.分別抽取出來每個學校的參賽信息(按學校分羣,高校名做索引)
4.統計每個學校的參賽信息
··· 4.1.設計存儲每一個學校參賽相關信息的數據結構
··· 4.2.分別統計每一個大學的各個賽題參與和完成獲獎情況
··· 這裏由宏觀到微觀鋪開整個數據結構的組織結果:
··· ···A.宏觀(全部高校參賽情況對象字典,每一個高校參賽情況對象記爲xuexiao1)
··· ···B.微觀:xuexiao1對象的展開
··· ···C.xuexiao1對象中的"學校各題獲獎明細"展開
5.統計shanghai地區大學的參賽情況
····5.1.統計shanghai地區大學的參賽情況
····5.2.統計shanghai地區部分大學的參賽獲獎情況
····5.3.統計全國參賽的情況
注:由於學生隊伍成員組隊方式的靈活性,本文將以隊伍爲研究粒度來做統計分析。
6.參賽人數的統計
7.每個大學"答題明細"對象挖掘分析
以同濟大學和SMU大學爲例。
··· 7.2.1.兩個學校6道賽題完成情況一覽
··· 7.2.2.兩個學校6道賽題一等獎情況一覽
··· 7.2.3.高校數模戰鬥力排行榜(取戰鬥力前100名高校)

實現過程

1. 將6張擬獲獎名單進行拼接

1.1.1.將6張表橫向拼接;

import pandas as pd
import xlwt
import numpy as np
file_path=r'C:/Users/Administrator/Desktop/AAA/'
data_A=pd.read_excel(file_path+'2018年最終獲獎名單_A題.xls',encode='gbk')
len(data_A) #678
data_A.columns.tolist()  
#['序號', '題號', '隊伍編號', '獎項', '隊長姓名', '隊長所在單位', '第一隊友姓名', '第一隊友所在單位', '第二隊友姓名', '第二隊友所在單位']
data_B=pd.read_excel(file_path+'2018年最終獲獎名單_B題.xls',encode='gbk')
len(data_B) #1899
data_C=pd.read_excel(file_path+'2018年最終獲獎名單_C題.xls',encode='gbk')
len(data_C) #5560
data_D=pd.read_excel(file_path+'2018年最終獲獎名單_D題.xls',encode='gbk')
len(data_D) #557
data_E=pd.read_excel(file_path+'2018年最終獲獎名單_E題.xls',encode='gbk')
len(data_E) #1509
data_F=pd.read_excel(file_path+'2018年最終獲獎名單_F題.xls',encode='gbk')
len(data_F) #2004
data_all=pd.concat([data_A,data_B,data_C,data_D,data_E,data_F],axis=1) 
#橫向拼接設置axis=1,沿着水平方向來拼接。
print(data_all.head(10))
len(data_all)   #5560
#data_all拼接後的維度大小爲:rownum x 6*columnnum
rownum=max([len(data_A),len(data_B),len(data_C),len(data_D),len(data_E),len(data_F)])
columnnum=len(data_A.columns.tolist()  )
print(data_all.head(5))   #出於尊重他人隱私的目的,詳細的結果不在此給出,後續也希望參看該篇博客文章練習的同學勿輕易泄露他人信息爲盼!!!

1.1.2.將6張表縱向拼接;

import pandas as pd
import xlwt
import numpy as np
file_path=r'C:/Users/Administrator/Desktop/AAA/'
data_A=pd.read_excel(file_path+'2018年最終獲獎名單_A題.xls',encode='gbk')
len(data_A) #678
data_A.columns.tolist()  
#['序號', '題號', '隊伍編號', '獎項', '隊長姓名', '隊長所在單位', '第一隊友姓名', '第一隊友所在單位', '第二隊友姓名', '第二隊友所在單位']
data_B=pd.read_excel(file_path+'2018年最終獲獎名單_B題.xls',encode='gbk')
len(data_B) #1899
data_C=pd.read_excel(file_path+'2018年最終獲獎名單_C題.xls',encode='gbk')
len(data_C) #5560
data_D=pd.read_excel(file_path+'2018年最終獲獎名單_D題.xls',encode='gbk')
len(data_D) #557
data_E=pd.read_excel(file_path+'2018年最終獲獎名單_E題.xls',encode='gbk')
len(data_E) #1509
data_F=pd.read_excel(file_path+'2018年最終獲獎名單_F題.xls',encode='gbk')
len(data_F) #2004
data_all=pd.concat([data_A,data_B,data_C,data_D,data_E,data_F],axis=0) 
#橫向拼接設置axis=0,沿着豎直方向來拼接。
print(data_all.head(10))
len(data_all)   #5560
#data_all拼接後的維度大小爲:rownum x columnnum
rownum=sum([len(data_A),len(data_B),len(data_C),len(data_D),len(data_E),len(data_F)]) #12207
columnnum=len(data_A.columns.tolist())    #10
print(data_all.head(5))   #出於尊重他人隱私的目的,詳細的結果不在此給出,後續也希望參看該篇博客文章練習的同學勿輕易泄露他人信息爲盼!!!

1.1.3.簡單的檢索功能;

#1.檢索自己學校的參賽情況
file_path=r'C:/Users/Administrator/Desktop/AAA/'    #outputfile path
data_SMU=data_all[((data_all['隊長所在單位']=='XX大學')|
                                    (data_all['第一隊友所在單位']=='XX大學')|
                                    (data_all['第二隊友所在單位']=='XX大學'))]
data_SMU.to_excel(file_path+'XX大學2018研究生建模參賽信息彙總.xls',encoding='gbk')
#2.#1.獲獎隊伍
prized=data_SMU[~(data_SMU['獎項']=='成功參與獎')]
#2.未獲獎隊伍
unprized=data_SMU[data_SMU['獎項']=='成功參與獎']
prized['獎項'].value_counts()  #分別計算各個獎項獲獎隊伍數,默認是降序
"""
三等獎    63
二等獎    30
一等獎     3
"""
prizedCount=prized['獎項'].value_counts(ascending=True)
"""
一等獎     3
二等獎    30
三等獎    63
"""
unprizedCount=unprized['獎項'].value_counts() #計算成功參與獎的獲獎隊伍數
#成功參與獎    139
#2018華爲杯全國研究生數學建模,XX大學隊伍獲獎率
prizedsum=np.sum(prizedCount[:])
prizeate=np.sum(prizedCount)/(np.sum(unprizedCount)+prizedsum) # 0.4393063583815029
prizeate # 0.4393063583815029
#XX大學總人數佔2018年參賽隊伍比重
rate=sum(sum(prizedCount)+unprizedCount)/data_all.shape[0] #參賽總人數=12207
rate
#3."""1.發現數據中: 一等獎(華爲)和 一等獎同類異名,考慮去重複項併合並,使用正則表達式或者字符串替換"""
data_all['獎項']=data_all['獎項'].apply(lambda x:x.replace('一等獎(華爲)','一等獎')) #同類異名的合併
#4.全國的獲獎分層情況
chooses,category=[data_all['題號'].value_counts(ascending=True),data_all['獎項'].value_counts(ascending=True)]
chooses
category
totalNum=data_all.shape[0]
prize1_rate,prize2_rate,prize3_rate,unprize_rate=category/totalNum
print('\n一等獎: ',prize1_rate,'\n二等獎: ',prize2_rate,'\n三等獎: ',prize3_rate,'\n成功參與獎: ',unprize_rate)
#獲獎人數&未獲獎人數佔比
lucky_count=sum(category[:3]) #獲獎人數:4358
success_join_count=totalNum-lucky_count #未獲獎人數:7849
print('2018年華爲杯數學建模獲獎率: ',prize1_rate+(prize2_rate+prize3_rate))

效果:

一等獎:  0.015073318587695584 
二等獎:  0.13008929302859015 
三等獎:  0.21184566232489555 
成功參與獎:  0.6429917260588187
2018年華爲杯數學建模獲獎率:  0.3570082739411813

2.抽取參賽高校列表

#高校名稱列表
import pandas as pd
university_list=list(pd.concat([data_all['隊長所在單位'],data_all['第一隊友所在單位'],data_all['第二隊友所在單位']]).unique())
university_list
['華北電力大學',
 '吉林大學',
 '東北林業大學',
 '同濟大學',
 '華東師範大學',
 ……
 '美國康奈爾大學',
 '重慶醫科大學',
 '北京語言大學',
 '中共上海市委黨校',
 '香港大學',
 '新加坡國立大學',
 '中國人民公安大學',
 '中國航天科技集團公司航天時代電子公司(13所)',
 '中國航天科技集團公司第五研究院(511 所)',
 '中國航天科技集團公司第一研究院(14所)',
 '密歇根大學',
 '國家海洋局第一海洋研究所',
 '中國航天科工集團公司第三研究院(35所)',
 '中國地震局地球物理研究所',
 '中國航天科技集團公司第一研究院(703所)']

3.分別抽取出來每個學校的參賽信息(對學校分羣)

#分別抽取出來每個學校的參賽信息
#university=[] #將各個大學分羣
university={} #將各個大學分羣
totalNum=data_all.shape[0] #參賽隊伍總支數
for i in range(len(university_list)):
    #grade.append(university_list[i]+str(i))
    del data_SMU
    data_SMU=data_all[((data_all['隊長所在單位']==university_list[i])|(data_all['第一隊友所在單位']==university_list[i])|(data_all['第二隊友所在單位']==university_list[i]))].reset_index(drop=True)
    del data_SMU['序號']
    university[university_list[i]]=data_SMU
  

4.統計每個學校的參賽信息
4.1.設計存儲每一個學校參賽相關信息的數據結構

xuexiao1={'學校名稱':XX大學,
          '參賽人數':1000,
          '獲獎總隊伍數':480,
          '未獲獎總隊伍數':1000-480,
          '學校各題獲獎比率':[{‘A’:18.5%},{‘B’:28.5%},{C’:15.5%},{‘D’:38.5%},{‘C’:58.5%},{‘D’:48.5%}],
          '學校獲獎比':480/1000
          '學校各題獲獎明細':{
          'A':{'一等獎隊伍數':one_prize1, '一等獎獲獎比率':one_rate1,'二等獎隊伍數':two_prize1, '二等獎獲獎比率':two_rate1, '三等獎隊伍數':three_prize1,'三等獎獲獎比率':three_rate1,'成功參與獎隊伍數':non_prize1,'未獲獎比率':non_rate1, '獲獎隊伍數':award_prize,'獲獎比率':prized_rate1},
          'B':{'一等獎隊伍數':one_prize1, '一等獎獲獎比率':one_rate1,'二等獎隊伍數':two_prize1, '二等獎獲獎比率':two_rate1, '三等獎隊伍數':three_prize1,'三等獎獲獎比率':three_rate1,'成功參與獎隊伍數':non_prize1,'未獲獎比率':non_rate1, '獲獎隊伍數':award_prize,'獲獎比率':prized_rate1},
          'C':{'一等獎隊伍數':one_prize1, '一等獎獲獎比率':one_rate1,'二等獎隊伍數':two_prize1, '二等獎獲獎比率':two_rate1, '三等獎隊伍數':three_prize1,'三等獎獲獎比率':three_rate1,'成功參與獎隊伍數':non_prize1,'未獲獎比率':non_rate1, '獲獎隊伍數':award_prize,'獲獎比率':prized_rate1},
          'D':{'一等獎隊伍數':one_prize1, '一等獎獲獎比率':one_rate1,'二等獎隊伍數':two_prize1, '二等獎獲獎比率':two_rate1, '三等獎隊伍數':three_prize1,'三等獎獲獎比率':three_rate1,'成功參與獎隊伍數':non_prize1,'未獲獎比率':non_rate1, '獲獎隊伍數':award_prize,'獲獎比率':prized_rate1},
          'E':{'一等獎隊伍數':one_prize1, '一等獎獲獎比率':one_rate1,'二等獎隊伍數':two_prize1, '二等獎獲獎比率':two_rate1, '三等獎隊伍數':three_prize1,'三等獎獲獎比率':three_rate1,'成功參與獎隊伍數':non_prize1,'未獲獎比率':non_rate1, '獲獎隊伍數':award_prize,'獲獎比率':prized_rate1},
          'F':{'一等獎隊伍數':one_prize1, '一等獎獲獎比率':one_rate1,'二等獎隊伍數':two_prize1, '二等獎獲獎比率':two_rate1, '三等獎隊伍數':three_prize1,'三等獎獲獎比率':three_rate1,'成功參與獎隊伍數':non_prize1,'未獲獎比率':non_rate1, '獲獎隊伍數':award_prize,'獲獎比率':prized_rate1}
            }
          }
          

4.2.分別統計每一個大學的各個賽題參與和完成獲獎情況

totalUniv={}
saiti_list=['A','B','C','D','E','F']
for i in range(len(university)):
#for i in range(5):
    #print(university[university_list[0]]) #university爲字典,學校名稱爲key
    xiexiao={}
     #xiexiao1=university[university_list[3]]
    xiexiao1=university[university_list[i]]
    #xiexiao1=university[university_list[77]] #3--同濟大學,77--海事大學
    #學校名稱(三列中的衆數)
    zhongshu=pd.concat([xiexiao1['隊長所在單位'],xiexiao1['第一隊友所在單位'],xiexiao1['第二隊友所在單位']]) #Series
    xiexiao['學校名稱']= zhongshu.value_counts().index[0] #value_counts默認是降序,選擇衆數對應的索引值即爲學校.
    #chooses=xiexiao1['題號'].value_counts(ascending=True) #對應賽題選做隊伍支數
    ##A=xiexiao1[xiexiao1['題號']].value_counts()
    #prizeoption=xiexiao1['獎項'].unique()
    #1.分析獲獎總人數
    xiexiao['參賽隊伍']=len(xiexiao1)
    #totalUniv[university_list[3]]=xiexiao
    #totalUniv[university_list[i]]=xiexiao
    #2.分析該學校的各個賽題完成情況
    #2.1.選做A題的情況
    #xiexiao1[xiexiao1['題號']=='A']['獎項'].value_counts(ascending=True) #返回A賽題對應的獲獎情況
    #2.2.六道賽題各自獲獎情況一覽表
    """
    zhou=[1,2,4,5],zhou[-1],zhou[:-1]
    """
    timu={}#存放六道賽題各自對應的獲獎情況
    sum_prize1=0
    award_prize=0
    for ii in range(len(saiti_list)):
        #print(saiti_list[ii])
        #things=things.index
        #必須對things進行初始化,不然有的學校沒有一等獎things[0]就錯位了,就出錯了.
        things=xiexiao1[xiexiao1['題號']==saiti_list[ii]]['獎項'].value_counts(ascending=True)
        #發現同濟大學有B,但是B題目沒有一等獎
        #things=xiexiao1[xiexiao1['題號']==saiti_list[ii]]['獎項'].value_counts(ascending=True)
        ##賦初值,因爲每個獎不一定都有.
        one_rate1=0
        two_rate1=0
        three_rate1=0
        non_rate1=0
        prized_rate1=0
        try:
            #一等獎隊伍數
            try:
                if ~things[things.index=='一等獎'].empty:
                    #print('1')
                    one_prize1=things[things.index=='一等獎'] #type(one_prize1)=Series
                    if len(one_prize1)==0:
                        one_prize1=0
                    elif len(one_prize1)==1:
                        #one_prize1=one_prize1.values[0,0] #將Series轉換爲二維數組
                        one_prize1=list(one_prize1)[0] #將Series轉換爲list在取值也可以
                else:
                    one_prize1=0
            except  :
                pass
            finally:
                print('one_prize1出錯啦!!!!!!!!!!!')    
            #二等獎人數
            try:
                if ~things[things.index=='二等獎'].empty:
                    two_prize1=things[things.index=='二等獎']
                    if len(two_prize1)==0:
                        two_prize1=0
                    elif len(two_prize1)==1:
                        #one_prize1=one_prize1.values[0,0] #將Series轉換爲二維數組
                        two_prize1=list(two_prize1)[0] #將Series轉換爲list在取值也可以
                else:
                    two_prize1=0
            except  :
                pass
            finally:
                print('two_prize1出錯啦!!!!!!!!!!!')  
            #三等獎隊伍數
            try:
                if ~things[things.index=='三等獎'].empty:
                    three_prize1=things[things.index=='三等獎']
                    if len(three_prize1)==0:
                        three_prize1=0
                    elif len(three_prize1)==1:
                        #one_prize1=one_prize1.values[0,0] #將Series轉換爲二維數組
                        three_prize1=list(three_prize1)[0] #將Series轉換爲list在取值也可以
                else:
                    three_prize1=0
            except  :
                pass
            finally:
                print('three_prize1出錯啦!!!!!!!!!!!')
            #成功參與獎隊伍數===未獲獎人數
            try:
                if ~things[things.index=='成功參與獎'].empty:
                    non_prize1=things[things.index=='成功參與獎']
                    if len(non_prize1)==0:
                        non_prize1=0
                    elif len(non_prize1)==1:
                        #one_prize1=one_prize1.values[0,0] #將Series轉換爲二維數組
                        non_prize1=list(non_prize1)[0] #將Series轉換爲list在取值也可以
                else:
                    non_prize1=0
            except  :
                pass
            finally:
                print('non_prize1出錯啦!!!!!!!!!!!')
            #獲獎隊伍總數
            award_prize=sum(things[:-1])
            #某道賽題的參賽總隊伍數
            sum_prize1=sum(things)
            #一等獎隊伍與該賽題參賽隊伍總數的佔比
            one_rate1=one_prize1/sum_prize1
            #二等獎隊伍與該賽題參賽隊伍總數的佔比
            two_rate1=two_prize1/sum_prize1
            #三等獎隊伍與該賽題參賽隊伍總數的佔比
            three_rate1=three_prize1/sum_prize1
            #未獲獎隊伍與該賽題參賽隊伍總數的佔比
            non_rate1=non_prize1/sum_prize1
            #獲獎隊伍與該賽題參賽隊伍總數的佔比
            prized_rate1=award_prize/sum_prize1
            timu[saiti_list[ii]]={
                    '一等獎隊伍數':one_prize1,
                    '一等獎獲獎比率':one_rate1,
                    '二等獎隊伍數':two_prize1,
                    '二等獎獲獎比率':two_rate1,
                    '三等獎隊伍數':three_prize1,
                    '三等獎獲獎比率':three_rate1,
                    '成功參與獎隊伍數':non_prize1,'未獲獎比率':non_rate1,
                    '獲獎隊伍數':award_prize,'獲獎比率':prized_rate1}
            #del things
        except  :
            pass
        #finally:
        #     print('出錯啦!!!!!!!!!!!')
    #3.獲獎總人數
    try:
        total_queue=0
        for i1 in range(len(timu)):
            try:
                total_queue+=timu[saiti_list[i1]]['獲獎隊伍數']
            except:
                continue
        xiexiao['獲獎總隊伍數']=total_queue
    except:
            pass
    #4.未獲獎總人數
    try:
        un_num=0
        for i1 in range(len(timu)):
            try:
                un_num+=timu[saiti_list[i1]]['成功參與獎隊伍數']
            except:
                continue
        xiexiao['未獲獎總隊伍數']=un_num
    except:
            pass
    #5.某賽題獲獎情況本質上爲一個list=[]對象
    try:
        rate_list={}
        for i1 in range(len(timu)):
            rate_list[saiti_list[i1]]=timu[saiti_list[i1]]['獲獎比率']
        xiexiao['學校各題獲獎比率']=rate_list
    except:
            pass
    #5.學校各道賽題完成獲獎情況
    try:
        xiexiao['學校各題獲獎明細']=timu
    except:
            pass
    #5.學校獲獎比
    try:
        xx_rate=total_queue/len(xiexiao1) #學校的參與競賽總人數
        xiexiao['學校獲獎比']=xx_rate
    except:
            pass
    #totalUniv.append(xiexiao)
    totalUniv[university_list[i]]=xiexiao
    del xiexiao1
    
#保存字典數據:使用DataFrame
import pandas as pd
data=pd.DataFrame(totalUniv,columns=totalUniv.keys()).T
columns_name=data.columns.tolist()
#各列數值不變的條件下來重命名各列
#data.columns=[['參賽隊伍', '學校各題獲獎明細', '學校各題獲獎比率', '學校名稱', '學校獲獎比', '未獲獎總隊伍數', '獲獎總隊伍數']]
#各列隨着名稱先後順序發生位置變化
data=pd.DataFrame(totalUniv,columns=totalUniv.keys()).T
#重新指定列的順序
data=data[['學校名稱','參賽隊伍', '獲獎總隊伍數', '未獲獎總隊伍數','學校各題獲獎明細', '學校各題獲獎比率',  '學校獲獎比']]
#data[data['學校名稱']=='XX大學']
data.to_csv('E:/jpzhou.csv',index=False)

這裏由宏觀到微觀鋪開整個數據結構的組織結果:
A.宏觀:
在這裏插入圖片描述
B.微觀:xuexiao1對象的展開
在這裏插入圖片描述

C.xuexiao1對象中的"學校各題獲獎明細"展開
在這裏插入圖片描述

5.統計shanghai地區大學的參賽情況
····5.1.統計shanghai地區大學的參賽情況

#按照參賽人數對字典進行排序
join_party={}
for i in range(len(university_list)):
#for i in range(5):
    #print(university[university_list[0]]) #university爲字典,學校名稱爲key
    try:
        xiexiao1=totalUniv[university_list[i]]
        num=int(xiexiao1['參賽隊伍'])
        join_party[str(university_list[i])]=num
        print(xiexiao1)
    except:
        continue
univ_totalnum=list(sorted(join_party.items(),key=lambda x:x[1],reverse=True)) #默認升序,True爲降序.
#上海各個高效參賽隊伍直方圖
#篩選出上海的高校
shanghai_univ=[]
for i in range(len(univ_totalnum)):
    for item in ['上海','華東','東華','同濟','復旦','解放軍第二軍醫']:
        if item in univ_totalnum[i][0]:
            shanghai_univ.append(univ_totalnum[i])
        else:
            continue
#刪除離羣點非上海的高校
del shanghai_univ[9]  #刪除中國石油大學(華東)---青島
del shanghai_univ[12] #華東交通大學----江西  
#獲得上海高校列表34所
#畫出直方圖
import matplotlib.pyplot as plt
plt.subplots(figsize=(10,6))
plt.rcParams['font.sans-serif'] = ['SimHei']  #用來顯示中文
plt.bar(range(len(shanghai_univ)),[shanghai_univ[i][1] for i in range(len(shanghai_univ))],color='blue',align='center')
plt.title("上海各高校2018年'華爲杯'全國研究生數學建模競賽參賽隊伍直方圖")
plt.xticks(range(len(shanghai_univ)),[shanghai_univ[i][0] for i in range(len(shanghai_univ))],rotation=90)
plt.xlim([-1,len(shanghai_univ)])
plt.xlabel("上海高校")
plt.ylabel("隊伍數")
plt.tight_layout()
plt.show()            
shanghai_university=shanghai_univ
type(shanghai_university[0][0])
type(shanghai_university[0][1])

shanghai_university=shanghai_univ
type(shanghai_university[0][0])
type(shanghai_university[0][1])


#將上海高校參賽數據入數據庫保存
import sqlite3
conn=sqlite3.connect('E:/代碼練習區256/MathModel/cmath2018.sqlite')
curs=conn.cursor()
#conn.close()
#在Python中一個分號算是一條語句,curs.execute(sql(i))只執行一條語句
curs.execute("drop table if EXISTS unives_shanghai");
#curs.close()
curs.execute("create table unives_shanghai(uid varchar(10) PRIMARY KEY,univ_name varchar(30),groupe_num int)")
#curs.execute("insert into unives_shanghai(uid,univ_name,groupe_num) values('123456','中國科學技術大學',240)") #% ('123456','中國科學技術大學',240))

id1='10247'+str(1)
name1=shanghai_university[1][0]
num1=shanghai_university[1][1]
#print("統計的數學===(%s,%s,%d)" % (id1,name1,num1))
#curs.execute("insert into unives_shanghai(uid,univ_name,groupe_num) values('%s','%s','%d')" % (id1,name1,num1)) #% ('123456','中國科學技術大學',240))

curs.execute("select * from unives_shanghai")
df1=curs.fetchall()

#for i in range(2,len(shanghai_university)):
for i in range(len(shanghai_university)):
    try:
        curs.execute("insert into unives_shanghai(uid,univ_name,groupe_num) values('%s','%s','%d')" % ('10247'+str(i),shanghai_university[i][0],shanghai_university[i][1]))
    except Exception as ex:  #異常的拋出
        print("Exception: ", str(ex))
        pass

curs.execute("select * from unives_shanghai")
df1=curs.fetchall()
#挑選出來上海地區參賽隊伍數>=100的學校
curs.execute("select * from unives_shanghai where groupe_num>=100")
df1=curs.fetchall()

在這裏插入圖片描述
註釋1:
insert錯誤
curs.execute(“insert into unives_shanghai(univ_name,groupe_num) values(%s,%d)” % (‘zhonguo’,240))
OperationalError: no such column: zhonguo
解決辦法: values中%s需要打單冒號’ ‘或者雙引號" "。
curs.execute("insert into unives_shanghai(uid,univ_name,groupe_num) values(’%s’,’%s’,’%d’)" % (id1,name1,num1)) #% (‘123456’,‘XX大學’,240))

····5.2.統計shanghai地區部分大學的參賽獲獎情況

#篩選出來上海各個高校的獲獎情況
shanghai_get={}
for i in range(len(shanghai_university)):
    shanghai_get[shanghai_university[i][0]]=totalUniv[shanghai_university[i][0]]
#畫出獲獎高校獲獎隊伍數直方圖
#排序前    
import matplotlib.pyplot as plt
plt.subplots(figsize=(10,6))
plt.rcParams['font.sans-serif'] = ['SimHei']  #用來顯示中文
#for i in shanghai_get:
#    print(i)
plt.bar(range(len(shanghai_get)),[shanghai_get[i]['獲獎總隊伍數'] for i in shanghai_get],color='blue',align='center')
plt.title("上海各高校2018年'華爲杯'全國研究生數學建模競賽獲獎隊伍直方圖")
plt.xticks(range(len(shanghai_get)),[shanghai_get[i]['學校名稱'] for i in shanghai_get],rotation=90)
plt.xlim([-1,len(shanghai_get)])
plt.xlabel("上海高校")
plt.ylabel("獲獎隊伍數")
plt.tight_layout()
plt.show() 
#排序後:數據複雜不好弄,單獨取出來再做分析,簡化操作過程
namename={}
for i in shanghai_get:
    namename[i]=shanghai_get[i]['獲獎總隊伍數']
zhouzhou=sorted(namename.items(),key=lambda x:x[1],reverse=True)
import matplotlib.pyplot as plt
plt.subplots(figsize=(10,6))
plt.rcParams['font.sans-serif'] = ['SimHei']  #用來顯示中文
plt.bar(range(len(zhouzhou)),[zhouzhou[i][1] for i in range(len(zhouzhou))],color='blue',align='center')
plt.title("上海各高校2018年'華爲杯'全國研究生數學建模競賽獲獎隊伍直方圖")
plt.xticks(range(len(zhouzhou)),[zhouzhou[i][0] for i in  range(len(zhouzhou))],rotation=90)
plt.xlim([-1,len(zhouzhou)])
plt.xlabel("上海高校")
plt.ylabel("獲獎隊伍數")
plt.tight_layout()
plt.show()
import pandas as pd
data2=pd.DataFrame(shanghai_get,columns=shanghai_get.keys()).T
columns2=data2.columns.tolist()
data2=data2[[ '學校名稱','參賽隊伍', '獲獎總隊伍數', '未獲獎總隊伍數', '學校獲獎比', '學校各題獲獎比率']]
data2.to_csv('E:/上海高校數模獲獎_data.csv',index=False)

A.排序前:
在這裏插入圖片描述
B.排序後:
在這裏插入圖片描述在這裏插入圖片描述
備註2:上圖僅節選了部分代表性高校做展示,另外爲方便數據展示,對高校獲獎率*1000,滬上各個高校的實際獲獎率=圖上獲獎率數值/1000。

5.3.統計全國的情況

#全國的情況
shouzhou=sorted(join_party.items(),key=lambda x:x[1],reverse=True)
import pandas as pd
data2=pd.DataFrame(shouzhou,columns=['學校','參賽隊伍數'])
columns2=data2.columns.tolist()
data2.to_csv('E:/全國高校數模參賽人數_data.csv',index=True)
#全國有實力高效的獲獎情況
import pandas as pd
data2=pd.DataFrame([totalUniv[i] for i in totalUniv],index=totalUniv.keys())
columns2=data2.columns.tolist()
#指定DataFrame各列的順序
data2=data2[['學校名稱', '參賽隊伍', '獲獎總隊伍數','未獲獎總隊伍數', '學校各題獲獎比率', '學校獲獎比']]
#data2.reindex(range(len(data2.index.tolist()))) #直接傳入想要的新index即可。但是很多東西沒了
data2.to_csv('E:/全國數模獲獎高校戰果統計_data.csv',index=False)

在這裏插入圖片描述在這裏插入圖片描述備註3:波峯部分都是參賽人數較多的院校。
備註4:
在這裏插入圖片描述
在這裏插入圖片描述獲獎率=該校獲獎隊伍數/該校參賽總隊伍數,獲獎率依然是一個學校整體實力的表徵,儘管參賽人數少,可能獲獎率高,一定程度上參賽隊伍數衆多的情況下,某個學校依然表現出整體的獲獎率超過50%,不得不說這個學校整體學生的水平是值得點讚的!
在這裏插入圖片描述
6.參賽人數的統計

#大致可以參考如下思路來嘗試完成
mouxiaoTotalnum=0
for i in range(len(data_all)):
	#三個隊員均來自本校
	if data_all[i]['隊長所在單位']=='XX大學')&
                                    (data_all[i]['第一隊友所在單位']=='XX大學')&
                                    (data_all[i]['第二隊友所在單位']=='XX大學')):
               mouxiaoTotalnum+=3   
         #僅兩個隊員均來自本校
	elif ((data_all[i]['隊長所在單位']=='XX大學')&
                                    (data_all[i]['第一隊友所在單位']=='XX大學')) or 
              ((data_all[i]['第一隊友所在單位']=='XX大學')&
               (data_all[i]['第二隊友所在單位']=='XX大學'))   or
                 ((data_all[i]['隊長所在單位']=='XX大學') &
                                    (data_all[i]['第二隊友所在單位']=='XX大學')):
               mouxiaoTotalnum+=2  
         #僅一個隊員均來自本校
        elif (data_all[i]['隊長所在單位']=='XX大學') or
                                    (data_all[i]['第一隊友所在單位']=='XX大學')  or
                                    (data_all[i]['第二隊友所在單位']=='XX大學'):
               mouxiaoTotalnum+=1    
               

7.每個大學"答題明細"對象挖掘分析
以同濟大學和SMU大學爲例。


#繪製SMU大學和同濟大學的答題情況
"""
數據結構設計:
item\賽題 A  B  C  D  E  F 
1   A1    B1    C1    D1    E1    F1  
2   A2    B2    C2    D2    E2    F2  
3   A3    B3    C3    D3    E3    F3  
4   A4    B4    C4    D4    E4    F4  
5   A5    B5    C5    D5    E5    F5  
6   A6    B6    C6    D6    E6    F6  
7   A7    B7    C7    D7    E7    F7  
8   A8    B8    C8    D8    E8    F8  
9   A9    B9    C9    D9    E9    F9  
10  A10   B10   C10   D10   E10   F10  
11  A11   B11   C11   D11   E11   F11  

"""
#知識點:
#1.使用矩陣(Array)的轉置,np.Array().T
#2.tuple/List的轉置使用列表的解析式
saiti_list=['A','B','C','D','E','F']
zhou111=[]
for i in range(6):
    shou=[]
    for j in range(11):
        shou.append(saiti_list[i]+str(j+1))
    zhou111.append(shou)
"""
['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'A11']
['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'B10', 'B11']
['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'C10', 'C11']
['D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'D10', 'D11']
['E1', 'E2', 'E3', 'E4', 'E5', 'E6', 'E7', 'E8', 'E9', 'E10', 'E11']
['F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11']
"""
#將list/tuple做轉置
grid = [[row[i] for row in zhou111] for i in range(len(zhou111[0]))]  
"""
['A1', 'B1', 'C1', 'D1', 'E1', 'F1']
['A2', 'B2', 'C2', 'D2', 'E2', 'F2']
['A3', 'B3', 'C3', 'D3', 'E3', 'F3']
['A4', 'B4', 'C4', 'D4', 'E4', 'F4']
['A5', 'B5', 'C5', 'D5', 'E5', 'F5']
['A6', 'B6', 'C6', 'D6', 'E6', 'F6']
['A7', 'B7', 'C7', 'D7', 'E7', 'F7']
['A8', 'B8', 'C8', 'D8', 'E8', 'F8']
['A9', 'B9', 'C9', 'D9', 'E9', 'F9']
['A10', 'B10', 'C10', 'D10', 'E10', 'F10']
['A11', 'B11', 'C11', 'D11', 'E11', 'F11']
"""
#SMU_data1=totalUniv[university_list[77]]  #同濟大學3,上海海事大學77.
SMU_data1=totalUniv[university_list[3]]
MingXi=SMU_data1['學校各題獲獎明細']
huizongTable=[]
saiti_list=['A','B','C','D','E','F']
mixname=MingXi[saiti_list[i]].keys()
#指定按照這個順序來實現信息抽取
itemlist=['一等獎隊伍數','一等獎獲獎比率','二等獎隊伍數',  '二等獎獲獎比率',  '三等獎隊伍數', '三等獎獲獎比率','獲獎隊伍數','獲獎比率','成功參與獎隊伍數', '未獲獎比率']
len(itemlist)
renlist=['獲獎隊伍數','成功參與獎隊伍數']
for i in range(len(saiti_list)):
    item=MingXi[saiti_list[i]] #取到每一道題的作答情況
    shou=[]
    #for j in range(10):
    #    shou.append(item[itemlist[j]])
    item1=item[itemlist[0]] #一等獎隊伍數
    shou.append(item1)
    item2=item[itemlist[1]]*100 #一等獎獲獎比率,爲方便可視化這裏*100
    shou.append(item2)
    item3=item[itemlist[2]] #二等獎隊伍數
    shou.append(item3)
    item4=item[itemlist[3]]*100 #二等獎獲獎比率
    shou.append(item4)
    item5=item[itemlist[4]] #三等獎隊伍數
    shou.append(item5)
    item6=item[itemlist[5]]*100 #三等獎獲獎比率
    shou.append(item6)
    item7=item[itemlist[6]] #獲獎隊伍數
    shou.append(item7)
    item8=item[itemlist[7]]*100 #獲獎比率
    shou.append(item8)
    item9=item[itemlist[8]] #成功參與獎隊伍數 
    shou.append(item9)
    item10=item[itemlist[9]]*100 #未獲獎比率
    shou.append(item10)
    zongren=item[renlist[0]]+item[renlist[1]]
    shou.append(zongren)
    huizongTable.append(shou)
#將彙總表做轉置
#ScoreTable= [[row[i] for row in huizongTable] for i in range(len(huizongTable[0]))]  
ScoreTable=np.array(huizongTable).T  #轉換成爲numpy.array()後直接複製到Excel中處理分析即可
#空白記事本中替換無關的[,],',等等,換行頂格寫,直接粘貼到Excel可以識別自動填充cell。


def Audit_Univ(output_path,univ_index):
    #SMU_data1=totalUniv[university_list[3]]
    SMU_data1=totalUniv[university_list[univ_index]]
    MingXi=SMU_data1['學校各題獲獎明細']
    huizongTable=[]
    saiti_list=['A','B','C','D','E','F']
    #mixname=MingXi[saiti_list[i]].keys()
    #指定按照這個順序來實現信息抽取
    itemlist=['一等獎隊伍數','一等獎獲獎比率','二等獎隊伍數',  '二等獎獲獎比率',  '三等獎隊伍數', '三等獎獲獎比率','獲獎隊伍數','獲獎比率','成功參與獎隊伍數', '未獲獎比率']
    len(itemlist)
    renlist=['獲獎隊伍數','成功參與獎隊伍數']
    for i in range(len(saiti_list)):
        item=MingXi[saiti_list[i]] #取到每一道題的作答情況
        shou=[]
        #for j in range(10):
        #    shou.append(item[itemlist[j]])
        item1=item[itemlist[0]] #一等獎隊伍數
        shou.append(item1)
        item2=item[itemlist[1]]*100 #一等獎獲獎比率,爲方便可視化這裏*100
        shou.append(item2)
        item3=item[itemlist[2]] #二等獎隊伍數
        shou.append(item3)
        item4=item[itemlist[3]]*100 #二等獎獲獎比率
        shou.append(item4)
        item5=item[itemlist[4]] #三等獎隊伍數
        shou.append(item5)
        item6=item[itemlist[5]]*100 #三等獎獲獎比率
        shou.append(item6)
        item7=item[itemlist[6]] #獲獎隊伍數
        shou.append(item7)
        item8=item[itemlist[7]]*100 #獲獎比率
        shou.append(item8)
        item9=item[itemlist[8]] #成功參與獎隊伍數 
        shou.append(item9)
        item10=item[itemlist[9]]*100 #未獲獎比率
        shou.append(item10)
        zongren=item[renlist[0]]+item[renlist[1]]
        shou.append(zongren)
        huizongTable.append(shou)
    #將彙總表做轉置
    #ScoreTable= [[row[i] for row in huizongTable] for i in range(len(huizongTable[0]))]  
    ScoreTable=np.array(huizongTable).T
    #答案拼接方式
    
    output_path1=output_path+'2018華爲杯數學建模成績_'+university_list[univ_index]+'.csv'
    import pandas as pd
    index_list=[]
    for i in range(len(itemlist)):
        index_list.append(itemlist[i])
    index_list.append('參賽人數')
    data_univ=pd.DataFrame(ScoreTable,columns=saiti_list,index=index_list)
    data_univ.to_csv(output_path1)
#統計數據輸出
outpath_audit='E:/2018年華爲杯數學建模分析彙總/audit1112/'
Audit_Univ(outpath_audit,3)
#生成所有參賽院校的成績報表(然後在Excel表格中可以輕鬆地操作這些數據---散點圖、折線圖、直方圖、餅圖等等)
for i in range(len(university_list)):
    Audit_Univ(outpath_audit,i)

7.1.運行之後的表數據如下:

2018年華爲杯SMU數學建模完成情況一覽表						
						
······明細··	A	B	C	D	E	F
一等獎隊伍數	0	0	0	0	2	1
一等獎獲獎比率	0	0	0	0	6.66667	2.43902
二等獎隊伍數	0	2	16	0	5	7
二等獎獲獎比率	0	4.87805	15.3846	0	16.6667	17.0732
三等獎隊伍數	1	16	23	4	11	8
三等獎獲獎比率	8.33333	39.0244	22.1154	57.1429	36.6667	19.5122
獲獎隊伍數	1	18	39	3	18	16
獲獎比率	   8.33333	43.9024	37.5	42.8571	60	39.0244
成功參與獎隊伍數	11	23	65	3	12	25
未獲獎比率 	91.6667	56.0976	62.5	42.8571	40	60.9756
參賽人數	··12	41	104	6	30	41
						
						
						
						
2018年華爲杯同濟大學數學建模完成情況一覽表						
						
·····明細	A	B	C	D	E	F
一等獎隊伍數	1	0	1	1	2	1
一等獎獲獎比率	5	0	0.444444	2.32558	3.7037	0.763359
二等獎隊伍數	8	22	69	13	12	33
二等獎獲獎比率	40	20.9524	30.6667	30.2326	22.2222	25.1908
三等獎隊伍數	6	20	72	10	15	37
三等獎獲獎比率	30	19.0476	32	23.2558	27.7778	28.2443
獲獎隊伍數	12	42	142	24	29	71
獲獎比率	60	40	63.1111	55.814	53.7037	54.1985
成功參與獎隊伍數	5	63	83	19	25	60
未獲獎比率 	25	60	36.8889	44.186	46.2963	45.8015
參賽人數	17	105	225	43	54	131

7.2.將生成的.csv文件打開可以在Excel中直接做分析量化,在此不再贅述。如:
2018華爲杯數學建模成績_同濟大學.csv
2018華爲杯數學建模成績_SUM大學.csv
部分可視化分析效果如下:
7.2.1.兩個學校6道賽題完成情況一覽:
A.同濟大學:
在這裏插入圖片描述
B.SMU大學:
在這裏插入圖片描述
在這裏插入圖片描述
7.2.2.兩個學校6道賽題一等獎情況一覽:
A.同濟大學:
在這裏插入圖片描述
B.SMU大學:
在這裏插入圖片描述
7.2.3.高校數模戰鬥力排行榜(取戰鬥力前100名高校)
高校戰鬥力由各個等次的獎做加權求和。
一等獎權重:one_weight=0.3,二等獎權重:two_weight=0.17,
三等獎權重:three_weight=0.09,成功參與獎權重:canyu_weight=0.02

iter_zhanli={}
def Audit_Univ(output_path,univ_index):
    #SMU_data1=totalUniv[university_list[3]]
    SMU_data1=totalUniv[university_list[univ_index]]
    MingXi=SMU_data1['學校各題獲獎明細']
    huizongTable=[]
    saiti_list=['A','B','C','D','E','F']
    #mixname=MingXi[saiti_list[i]].keys()
    #指定按照這個順序來實現信息抽取
    itemlist=['一等獎隊伍數','一等獎獲獎比率','二等獎隊伍數',  '二等獎獲獎比率',  '三等獎隊伍數', '三等獎獲獎比率','獲獎隊伍數','獲獎比率','成功參與獎隊伍數', '未獲獎比率']
    len(itemlist)
    renlist=['獲獎隊伍數','成功參與獎隊伍數']
    zhanlili=0  #統計每個學校總的戰鬥力
    for i in range(len(saiti_list)):
        try:
            item=MingXi[saiti_list[i]] #取到每一道題的作答情況
        except:
            continue
        shou=[]
        #戰鬥力值矩陣
        zhandouli=0
        one_prizeli=0
        one_weight=0.3
        two_prizeli=0
        two_weight=0.17
        three_prizeli=0
        three_weight=0.09
        canyu_prizeli=0
        canyu_weight=0.02
        #for j in range(10):
        #    shou.append(item[itemlist[j]])
        item1=item[itemlist[0]] #一等獎隊伍數
        one_prizeli+=item1*one_weight #一等獎戰鬥力值累計
        shou.append(item1)
        item2=item[itemlist[1]]*100 #一等獎獲獎比率,爲方便可視化這裏*100
        shou.append(item2)
        item3=item[itemlist[2]] #二等獎隊伍數
        two_prizeli+=item3*two_weight #二等獎戰鬥力值累計
        shou.append(item3)
        item4=item[itemlist[3]]*100 #二等獎獲獎比率
        shou.append(item4)
        item5=item[itemlist[4]] #三等獎隊伍數
        three_prizeli+=item5*three_weight #三等獎戰鬥力值累計
        shou.append(item5)
        item6=item[itemlist[5]]*100 #三等獎獲獎比率
        shou.append(item6)
        item7=item[itemlist[6]] #獲獎隊伍數
        shou.append(item7)
        item8=item[itemlist[7]]*100 #獲獎比率
        shou.append(item8)
        item9=item[itemlist[8]] #成功參與獎隊伍數
        canyu_prizeli+=item9*canyu_weight
        shou.append(item9)
        item10=item[itemlist[9]]*100 #未獲獎比率
        shou.append(item10)
        zongren=item[renlist[0]]+item[renlist[1]]
        shou.append(zongren)
        #計算每道題目貢獻出來的戰鬥力值
        zhandouli=canyu_prizeli+three_prizeli+two_prizeli+one_prizeli
        shou.append(zhandouli)
        huizongTable.append(shou)
        zhanlili+=zhandouli
    #將彙總表做轉置
    #ScoreTable= [[row[i] for row in huizongTable] for i in range(len(huizongTable[0]))]  
    ScoreTable=np.array(huizongTable).T
    #各個學校的總戰鬥力值
    iter_zhanli[university_list[univ_index]]=zhanlili
    #答案拼接方式
    output_path1=output_path+'2018華爲杯數學建模成績_'+university_list[univ_index]+'.csv'
    import pandas as pd
    index_list=[]
    for i in range(len(itemlist)):
        index_list.append(itemlist[i])
    index_list.append('參賽人數')
    index_list.append('戰鬥力值')
    #data_univ=pd.DataFrame(ScoreTable,columns=saiti_list,index=index_list)
    #data_univ.to_csv(output_path1)
#統計數據輸出
outpath_audit='E:/2018年華爲杯數學建模分析彙總/audit1112/'
#Audit_Univ(outpath_audit,3)
#生成所有參賽院校的成績報表(然後在Excel表格中可以輕鬆地操作這些數據---散點圖、折線圖、直方圖、餅圖等等)
for i in range(len(university_list)):
    Audit_Univ(outpath_audit,i)


#各個高校戰鬥力值排名,因爲緊靠獲獎人數/參賽總人數會拉低很多參賽人數多的高校的戰鬥力值的量化
#對各個高校的戰鬥力值字典進行排序(各個獎項按照權重做加和獲得)
energyli=sorted(iter_zhanli.items() ,key=lambda x:x[1],reverse=True)
import matplotlib.pyplot as plt
plt.subplots(figsize=(30,15))
numnum1=100
plt.rcParams['font.sans-serif'] = ['SimHei']  #用來顯示中文
#plt.bar(range(len(energyli)),[energyli[i][1] for i in range(len(energyli))],color='blue',align='center')
plt.bar(range(len(energyli[:numnum1])),[energyli[i][1] for i in range(numnum1)],color='blue',align='center')
plt.title("全國各高校2018年'華爲杯'全國研究生數學建模高校戰鬥力排行榜")
#plt.xticks(range(len(energyli)),[energyli[i][0] for i in  range(len(energyli))],rotation=45)
#plt.xlim([-1,len(energyli)])
plt.xticks(range(numnum1),[energyli[i][0] for i in  range(numnum1)],rotation=90)
plt.xlim([-1,numnum1])
plt.xlabel("高校名稱")
plt.ylabel("戰鬥力能量值")
plt.tight_layout()
plt.show()

在這裏插入圖片描述
8.不足
本文代碼確實較多,相比較**Jean_V**的代碼不夠簡潔。
https://blog.csdn.net/CSDN_wujian/article/details/83961212
另外,針對組隊的情況,如果是一個隊來自於三個院校,本文是給每個高校都投票一次,可能存在給某些院校多累計了隊伍數。在Jean_V的代碼中每個隊伍只投票一次。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章