趙 圓 圓
(石家莊職業(yè)技術(shù)學(xué)院 信息工程系,河北 石家莊 050081)
Python語(yǔ)言是一種簡(jiǎn)單易學(xué)、擁有豐富庫(kù)的開源腳本語(yǔ)言,在人工智能、網(wǎng)絡(luò)爬蟲、數(shù)據(jù)分析等方面有著非常廣泛的應(yīng)用.本文使用Python 語(yǔ)言的第三方庫(kù)對(duì)學(xué)生成績(jī)進(jìn)行處理和分析,繪制出雷達(dá)圖、散點(diǎn)圖和餅狀圖,供教師進(jìn)行可視化分析,為課程教學(xué)效果的評(píng)估提供參考依據(jù).
程序設(shè)計(jì)語(yǔ)言包含機(jī)器語(yǔ)言、匯編語(yǔ)言和高級(jí)語(yǔ)言.機(jī)器語(yǔ)言指的是二進(jìn)制語(yǔ)言,是計(jì)算機(jī)可以直接執(zhí)行的程序設(shè)計(jì)語(yǔ)言,直接使用機(jī)器語(yǔ)言編寫程序比較繁瑣.匯編語(yǔ)言是一種比較低級(jí)的程序設(shè)計(jì)語(yǔ)言,不同的計(jì)算機(jī)結(jié)構(gòu)使用的匯編指令不同,所以在使用過(guò)程中具有一定的局限性[1].高級(jí)語(yǔ)言比較接近自然語(yǔ)言,在不同結(jié)構(gòu)的計(jì)算機(jī)上描述問題、解決問題的表述方式相同.高級(jí)語(yǔ)言分為靜態(tài)語(yǔ)言和腳本語(yǔ)言,靜態(tài)語(yǔ)言采用編譯執(zhí)行的方式,腳本語(yǔ)言采用解釋執(zhí)行的方式.Python語(yǔ)言簡(jiǎn)單易學(xué)、可移植、可擴(kuò)展[2].Python語(yǔ)言因其擁有的優(yōu)勢(shì),在2021年8月的TIOBE編程語(yǔ)言排行榜上位居第二[3].
Python語(yǔ)言擁有Numpy(科學(xué)計(jì)算庫(kù))、Matplotlib(數(shù)據(jù)可視化庫(kù))、Pandas(數(shù)據(jù)分析庫(kù))等專業(yè)功能強(qiáng)大的第三方庫(kù),為人工智能領(lǐng)域進(jìn)行科學(xué)的數(shù)據(jù)分析提供了較好的方法[4].
Numpy是Python語(yǔ)言中最常用的可以實(shí)現(xiàn)高性能科學(xué)計(jì)算和數(shù)據(jù)分析的庫(kù),使用該庫(kù)可以生成一個(gè)Ndarray對(duì)象,該對(duì)象為具有矢量運(yùn)算和復(fù)雜廣播能力的多維數(shù)組,無(wú)需使用循環(huán)語(yǔ)句就可對(duì)整組數(shù)據(jù)進(jìn)行快速運(yùn)算.本文使用Ndarray對(duì)象存儲(chǔ)和處理班級(jí)、課程名稱數(shù)組,班級(jí)、課程成績(jī)及平均成績(jī)數(shù)組.
Matplotlib是Python語(yǔ)言中繪制數(shù)組的2D 圖形庫(kù),具有強(qiáng)大的數(shù)據(jù)可視化繪圖功能.它源于數(shù)學(xué)軟件Matlab,有獨(dú)特的優(yōu)勢(shì).Matplotlib開源免費(fèi),雖然它屬于Python 語(yǔ)言的擴(kuò)展模塊,但它繼承了Python語(yǔ)言的面向?qū)ο笠鬃x、易維護(hù)等特點(diǎn).Matplotlib提供子模塊pyplot,該模塊中封裝了一套類似Matlab命令式的繪圖函數(shù),為編程開發(fā)人員提供了接口.開發(fā)人員只要調(diào)用pyplot模塊中的函數(shù),就可以快速繪圖及設(shè)置圖表的各種需求.pyplot模塊包含了一組快速生成基礎(chǔ)圖表的函數(shù),可以生成直方圖、條形圖、箱線圖和雷達(dá)圖等[5].本文使用pyplot模塊中的polar()函數(shù)對(duì)各班級(jí)、各門課程學(xué)生的平均成績(jī)進(jìn)行雷達(dá)圖的繪制,并以Python 程序設(shè)計(jì)課程成績(jī)?yōu)槔?進(jìn)行散點(diǎn)圖和餅狀圖的繪制.
Pandas是Python 語(yǔ)言中常用的基于Numpy的數(shù)據(jù)分析模塊,該模塊納入了大量的庫(kù)和標(biāo)準(zhǔn)數(shù)據(jù)模型,提供了快速高效、具有默認(rèn)和自定義索引的Series對(duì)象和DataFrame對(duì)象,支持在內(nèi)存數(shù)據(jù)結(jié)構(gòu)和不同文件格式中讀取和寫入數(shù)據(jù),并進(jìn)行快速、便捷處理,最終生成可視化圖表.本文使用Pandas從存放成績(jī)的Excel表格中導(dǎo)入學(xué)生成績(jī),且對(duì)異常數(shù)據(jù)進(jìn)行清洗.
某學(xué)校2019級(jí)計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)專業(yè)1班、2班和3班的學(xué)生第四學(xué)期期末考試后,教師需要處理和分析每個(gè)班6門專業(yè)課程(網(wǎng)絡(luò)設(shè)備調(diào)試、Linux系統(tǒng)操作與管理、數(shù)據(jù)恢復(fù)技術(shù)、網(wǎng)絡(luò)安全基礎(chǔ)、融合通信技術(shù)、Python程序設(shè)計(jì))的成績(jī),利用成績(jī)數(shù)據(jù)繪制評(píng)估圖,包含各班級(jí)、各門課程成績(jī)?cè)u(píng)估雷達(dá)圖.本文以Python 程序設(shè)計(jì)課程成績(jī)?yōu)槔L制的散點(diǎn)圖和餅狀圖.
將學(xué)生成績(jī)存放到Excel表格中,3個(gè)班的Python程序設(shè)計(jì)課程成績(jī)存放的文件名為“scores+班級(jí)號(hào)”,例如,scores1.xlsx代表1班的Python程序設(shè)計(jì)課程成績(jī),文件中表頭包含序號(hào)、學(xué)號(hào)、姓名、平時(shí)成績(jī)、期末考試成績(jī)、實(shí)驗(yàn)成績(jī)和綜合成績(jī)等7列數(shù)據(jù).每個(gè)班6門專業(yè)課的平均成績(jī)存放在averagesscores.xlsx文件中.
數(shù)據(jù)處理流程包含4個(gè)模塊,分別為打開文件模塊、獲取數(shù)據(jù)模塊、數(shù)據(jù)處理模塊和數(shù)據(jù)可視化模塊.數(shù)據(jù)處理流程圖見圖1.
打開存放課程平均成績(jī)的averagesscores.xlsx文件,進(jìn)行讀寫操作.Pandas提供了一系列讀寫不同格式文件的函數(shù),導(dǎo)入Pandas模塊,使用read_excel()函數(shù)以只讀方式打開文件,并將讀取的數(shù)據(jù)存放到DataFrame對(duì)象“df_obj”中.實(shí)現(xiàn)代碼如下:
import pandas as pd
df_obj=pd.read_excel(r′E:averagescore.xlsx′)
程序運(yùn)行后會(huì)得到存放每個(gè)班級(jí)每門專業(yè)課程平均成績(jī)的數(shù)據(jù),將其存放到“df_obj”對(duì)象中.同樣使用read_excel()函數(shù)分別打開存放各班級(jí)Python程序設(shè)計(jì)課程成績(jī)的文件,1班、2班、3班的實(shí)現(xiàn)代碼分別為:
df_obj1=pd.read_excel(r′E:scores1.xlsx′)
df_obj2=pd.read_excel(r′E:scores2.xlsx′)
df_obj3=pd.read_excel(r′E:scores3.xlsx′)
將讀取到的存放各班Python程序設(shè)計(jì)課程學(xué)習(xí)成績(jī)的文件數(shù)據(jù)分別存放到“df_obj1”,“df_obj2”和“df_obj3”對(duì)象中.
圖1 數(shù)據(jù)處理流程圖
2.2.2.1 獲取雷達(dá)圖數(shù)據(jù)模塊
從存放平均成績(jī)的“df_obj”對(duì)象中讀取繪制雷達(dá)圖的指標(biāo)和數(shù)據(jù).
(1)讀取課程名稱、班級(jí)名稱數(shù)組,確定分析指標(biāo)
從文件中獲取到的數(shù)據(jù)包含行與列的名稱和成績(jī),輸出從文件中讀取的“df_obj”數(shù)據(jù),見圖2.從數(shù)據(jù)中可以看出,課程名稱是DataFrame對(duì)象中的列索引,但不包含班級(jí)列索引,故通過(guò)DataFrame的屬性columns獲取列標(biāo)簽,再篩選出除了班級(jí)列索引以外的其他課程名稱,將篩選出的課程名稱存放到列表中.
圖2 原始數(shù)據(jù)輸出截圖
關(guān)鍵代碼如下:
columns=df_obj.column
course=[]#定義一個(gè)列表來(lái)存儲(chǔ)最后的課程名稱
for i in range(0,7):#循環(huán)遍歷
if i! =0:
course.append(columns[i])#篩選出需要的課程名稱,并將課程名稱放到新的numpy數(shù)組中
程序運(yùn)行完后可獲取到課程名稱數(shù)組,截圖見圖3.
圖3 課程名稱數(shù)組截圖
獲取班級(jí)名稱,班級(jí)名稱是DataFrame對(duì)象的第一列數(shù)據(jù).通過(guò)ilco屬性獲取到第一列數(shù)據(jù),列序列默認(rèn)從0開始,iloc屬性以二維矩陣的位置指標(biāo)(即0,1,2,…)作為參數(shù)來(lái)獲取某行的數(shù)據(jù).比如,iloc[0]表示獲取到的第一行數(shù)據(jù),通過(guò)iloc[:,n]獲取第n+1列的數(shù)據(jù).獲得第一列班級(jí)名稱后,需要將它轉(zhuǎn)換為一維數(shù)組,關(guān)鍵代碼如下:
df_clas=df_obj.iloc[:,0]
clas=df_clas.values #獲取到班級(jí)數(shù)組
獲取的班級(jí)數(shù)組截圖見圖4.
圖4 班級(jí)數(shù)組截圖
(2)讀取平均成績(jī),收集指標(biāo)數(shù)據(jù)
指標(biāo)數(shù)據(jù)是指原始數(shù)據(jù)中3個(gè)班級(jí)6門專業(yè)課程的平均成績(jī)數(shù)據(jù),即第二列至第六列數(shù)據(jù).使用iloc[:,1:7]命令獲取第二列到第六列數(shù)據(jù)后,將數(shù)據(jù)存儲(chǔ)到DataFrame對(duì)象中,使用屬性value獲得由數(shù)據(jù)組成的數(shù)組,并對(duì)數(shù)據(jù)進(jìn)行行列互換,得到6行3列的指標(biāo)數(shù)據(jù).關(guān)鍵代碼如下:
df_scores=df_obj.iloc[:,1:7]
data_scores=df_scores.values#返回DataFrame對(duì)象包含數(shù)據(jù)的數(shù)組,獲取到我們的數(shù)據(jù)
#行列互換才能得到繪圖的數(shù)據(jù)
scores=data_scores.T
最終指標(biāo)數(shù)據(jù)截圖見圖5.
圖5 指標(biāo)數(shù)據(jù)截圖
2.2.2.2 獲取散點(diǎn)圖數(shù)據(jù)模塊
以Python程序設(shè)計(jì)課程成績(jī)?yōu)槔?繪制各班成績(jī)散點(diǎn)圖.在原始數(shù)據(jù)文件scores1.xlsx,scores2.xlsx和scores3.xlsx中包含序號(hào)、學(xué)號(hào)、姓名、平時(shí)成績(jī)、期末成績(jī)、實(shí)驗(yàn)成績(jī)和綜合成績(jī)7列數(shù)據(jù),繪制散點(diǎn)圖只使用序號(hào)和綜合成績(jī)兩列數(shù)據(jù),顯示學(xué)生成績(jī)的離散情況.本文以獲取1班學(xué)生的Python程序設(shè)計(jì)課程成績(jī)?yōu)槔齺?lái)分析散點(diǎn)圖的數(shù)據(jù),具體實(shí)現(xiàn)代碼如下:
#獲取某列的數(shù)據(jù)
num1=df_obj1.iloc[:,0]#序號(hào)列
score7=df_obj1.iloc[:,6]#綜合成績(jī)列
通過(guò)DataFrame類型的“df_obj”對(duì)象的iloc屬性來(lái)獲取某行或某列的數(shù)據(jù),上述代碼中下標(biāo)0代表第一列,即獲取序號(hào)列數(shù)據(jù),下標(biāo)6代表第七列,即獲取綜合成績(jī)列數(shù)據(jù).同理,使用“df_obj2”對(duì)象的屬性、“df_obj3”對(duì)象的iloc屬性即可獲取2班和3班Python程序設(shè)計(jì)課程成績(jī)的散點(diǎn)圖數(shù)據(jù).
2.2.2.3 獲取餅狀圖數(shù)據(jù)模塊
以獲取1班學(xué)生的Python程序設(shè)計(jì)課程的綜合成績(jī)?yōu)槔?獲取各班級(jí)學(xué)生的Python 程序設(shè)計(jì)課程綜合成績(jī)的餅狀圖數(shù)據(jù),具體實(shí)現(xiàn)代碼如下:score7=df_obj1.iloc[:,6]#綜合成績(jī)列
通過(guò)DataFrame類型的“df_obj”對(duì)象的iloc屬性的下標(biāo)6獲取第七列綜合成績(jī)列的數(shù)據(jù).最終要根據(jù)綜合成績(jī)所在分?jǐn)?shù)段范圍([0,60)分、[60,70)分、[70,80)分、[80,90)分、[90,100]分)的人數(shù)繪制餅狀圖.在獲取綜合成績(jī)列的基礎(chǔ)上,需要統(tǒng)計(jì)綜合成績(jī)?cè)诓煌謹(jǐn)?shù)段的人數(shù)占比,實(shí)現(xiàn)代碼如下:
x1=[a/df_obj.size*100,b/df_obj.size*100,c/df_obj.size*100,d/df_obj.size*100,e/df_obj.size*100]
其中,代碼中變量a代表1 班綜合成績(jī)?cè)赱90,100]分的人數(shù);變量b代表綜合成績(jī)?cè)赱80,90)分的人數(shù);變量c代表綜合成績(jī)?cè)赱70,80)分的人數(shù);變量d代表綜合成績(jī)?cè)赱60,70)分的人數(shù);變量e代表綜合成績(jī)?cè)赱0,60)分的人數(shù);序列x1存儲(chǔ)的是各分?jǐn)?shù)段范圍的人數(shù)占總?cè)藬?shù)的百分比.
同理,分別使用“df_obj2”對(duì)象和“df_obj3”對(duì)象的iloc屬性獲取2班和3班學(xué)生的Python程序設(shè)計(jì)課程的綜合成績(jī),進(jìn)行不同分?jǐn)?shù)段范圍的人數(shù)統(tǒng)計(jì)并計(jì)算占比,存到序列x2和x3中.
讀取的數(shù)據(jù)中可能會(huì)帶有一些無(wú)效值,需將無(wú)效值替換為有效值.需要檢查是否有空值,若有空值,使用具體值0替換所有的空值.關(guān)鍵代碼如下:
df_obj.isnull()
df_obj.fillna(0)
2.2.4.1 繪制雷達(dá)圖
(1)將圓周等分
先獲取數(shù)據(jù)的長(zhǎng)度,命令為data_length=len(course),再將圓周等分為data_length份,關(guān)鍵代碼如下:
angles=np.linspace(0,2*np.pi,data_length,endpoint=False)
從0到2π,分成data_length等份.
(2)數(shù)據(jù)角度拼接,首尾相連
將數(shù)據(jù)和角度進(jìn)行拼接,首尾閉合.關(guān)鍵代碼如下:
scores= np.concatenate((scores,[scores[0]]))
angles= np.concatenate((angles,[angles[0]]))
course=np.concatenate((course,[course[0]]))
(3)繪制雷達(dá)圖
所有數(shù)據(jù)閉合后,使用polar繪制雷達(dá)圖.命令為plt.polar(angles,scores,′o-′,linewidth=3),第一個(gè)參數(shù)是角度,第二個(gè)參數(shù)是分?jǐn)?shù),第三和第四個(gè)參數(shù)是線條樣式.
(4)設(shè)置角度和網(wǎng)格標(biāo)簽
設(shè)置極坐標(biāo)的標(biāo)簽,并將標(biāo)簽放在六角形的頂點(diǎn)上.關(guān)鍵代碼如下:
plt.thetagrids(angles*180/np.pi,course,fontproperties=′simhei′)
plt.title(′成績(jī)?cè)u(píng)估′)設(shè)置圖的題目
plt.legend(clas,loc=(0.94,0.80),labelspacing=0.1)設(shè)置圖例
設(shè)置中文字符核心實(shí)現(xiàn)代碼如下:
plt.rcParams[′font.sans-serif′]=[′Sim Hei′]
plt.rcParams[′axes.unicode_minus′]=False
最后使用show()函數(shù)顯示成績(jī)?cè)u(píng)估雷達(dá)圖.
2.2.4.2 繪制散點(diǎn)圖
使用Matplotlib的pyplot模塊中scatter()函數(shù)繪制各班Python程序設(shè)計(jì)課程成績(jī)分布的散點(diǎn)圖.1班學(xué)生Python程序設(shè)計(jì)課程成績(jī)分布散點(diǎn)圖的具體實(shí)現(xiàn)代碼如下:
plt.scatter(num1,score7,s=50,c=′black′,marker=′o′,alpha=0.5)#散點(diǎn)圖
plt.title(“成績(jī)分布圖”)
其中,scatter函數(shù)的第一個(gè)參數(shù)num1是1班學(xué)生的Python 程序設(shè)計(jì)課程的第一列序號(hào)列數(shù)據(jù),第二個(gè)參數(shù)score7是綜合成績(jī)列數(shù)據(jù),第三個(gè)參數(shù)s=50設(shè)置的是散點(diǎn)圖中點(diǎn)的大小,第四個(gè)參數(shù)c=′black′設(shè)置散點(diǎn)圖中點(diǎn)的顏色為黑色,第五個(gè)參數(shù)market=′o′用于設(shè)置點(diǎn)的形狀,第六個(gè)參數(shù)alpha=0.5用于設(shè)置透明度,title屬性設(shè)置散點(diǎn)圖的標(biāo)題.
同理,可以繪制2班和3班學(xué)生的Python程序設(shè)計(jì)課程成績(jī)分布散點(diǎn)圖.
2.2.4.3 繪制餅狀圖
利用Matplotlib的pyplot模塊中pie()函數(shù)繪制各班學(xué)生Python程序設(shè)計(jì)課程不同分?jǐn)?shù)段成績(jī)的餅狀圖.以1班為例,具體實(shí)現(xiàn)代碼如下:
plt.pie(x1,labels=labels,autopct=′%3.2f%%′)
plt.axis(′equal′)
plt.title(“成績(jī)分布餅圖”)
plt.legend()
plt.show()
其中,pie()函數(shù)常用3個(gè)參數(shù),第一個(gè)參數(shù)x1是1班學(xué)生Python程序設(shè)計(jì)課程成績(jī)?cè)诓煌謹(jǐn)?shù)段的占比.“plt.axis(′equal′)”表示 繪圖的x軸和y軸范圍相同.title屬性設(shè)置餅狀圖的標(biāo)題.legend()函數(shù)為設(shè)置圖像圖例.“plt.show()”命令顯示繪制的圖像.
同理,可以繪制2班和3班學(xué)生Python程序設(shè)計(jì)課程成績(jī)?cè)诓煌謹(jǐn)?shù)段的餅狀圖.
在Python3.9 IDLE 下運(yùn)行程序,繪制出各班級(jí)、各課程的平均成績(jī)雷達(dá)圖,見圖6.繪制各班Python程序設(shè)計(jì)課程成績(jī)分布散點(diǎn)圖,見圖7-9.繪制各班Python 程序設(shè)計(jì)課程成績(jī)分布餅狀圖,見圖10-12.
圖6 各班級(jí)、各課程的平均成績(jī)雷達(dá)圖
圖7 1班Python程序設(shè)計(jì)課程成績(jī)分布散點(diǎn)圖
圖8 2班Python程序設(shè)計(jì)課程成績(jī)分布散點(diǎn)圖
圖9 3班Python程序設(shè)計(jì)課程成績(jī)分布散點(diǎn)圖
圖10 1班Python程序設(shè)計(jì)課程成績(jī)分布餅狀圖
圖11 2班Python程序設(shè)計(jì)課程成績(jī)分布餅狀圖
圖12 3班Python程序設(shè)計(jì)課程成績(jī)分布餅狀圖
雷達(dá)圖、散點(diǎn)圖和餅狀圖可以輔助教師從不同角度對(duì)學(xué)生成績(jī)進(jìn)行分析.
通過(guò)雷達(dá)圖可以全方位地看到3個(gè)班每門課程的平均成績(jī)及每個(gè)班級(jí)的優(yōu)勢(shì)科目和劣勢(shì)科目.從圖6可以看出,1班與其他兩個(gè)班相比,優(yōu)勢(shì)課程是融合通信技術(shù),劣勢(shì)課程是網(wǎng)絡(luò)安全基礎(chǔ);2班與其他兩個(gè)班相比,優(yōu)勢(shì)課程是網(wǎng)絡(luò)設(shè)備調(diào)試,劣勢(shì)課程相對(duì)不明顯;3班的相對(duì)優(yōu)勢(shì)課程是網(wǎng)絡(luò)基礎(chǔ)安全,相對(duì)劣勢(shì)課程是數(shù)據(jù)恢復(fù)技術(shù).
通過(guò)散點(diǎn)圖,可以直觀地看出各班學(xué)生成績(jī)的離散情況.從圖7-9可以看出,每個(gè)班大部分學(xué)生的成績(jī)都及格,而3班Python程序設(shè)計(jì)課程成績(jī)不及格的偏多,且低分學(xué)生相比另外兩個(gè)班數(shù)量也多,但是最高分也在其中.
通過(guò)餅狀圖可以看出,每個(gè)班級(jí)學(xué)生的成績(jī)分布情況.從圖10-11可以看出,1班和2班學(xué)生成績(jī)分布相對(duì)合理,大多集中在[60,90)分;在[0,60)分的,1班和2班人數(shù)較3班少,說(shuō)明這兩個(gè)班學(xué)生對(duì)課程內(nèi)容掌握得比較扎實(shí).從圖12可以看出,3班[0,60)分學(xué)生人數(shù)和[90~100]分的學(xué)生人數(shù)占比和其他分?jǐn)?shù)段范圍的人數(shù)占比相當(dāng),并未呈現(xiàn)出正態(tài)分布,說(shuō)明該班學(xué)生出現(xiàn)輕微的兩極分化現(xiàn)象;[0~60)分學(xué)生的人數(shù)占比較高,達(dá)25.81%,說(shuō)明3班的低分學(xué)生較多,課程學(xué)習(xí)效果相對(duì)差一些.
本文利用Python語(yǔ)言的第三方庫(kù)對(duì)學(xué)生成績(jī)進(jìn)行處理和分析,繪制出各班級(jí)、各課程成績(jī)的雷達(dá)圖、散點(diǎn)圖和餅狀圖,從不同角度直觀地反映學(xué)生的學(xué)習(xí)情況,幫助教師對(duì)比分析各個(gè)班級(jí)、各門課程的知識(shí)掌握情況及學(xué)習(xí)狀態(tài),指導(dǎo)教師有針對(duì)性地調(diào)整教學(xué)內(nèi)容、教學(xué)計(jì)劃等,以達(dá)到較好的教學(xué)效果.
石家莊職業(yè)技術(shù)學(xué)院學(xué)報(bào)2022年2期