Python分析成绩

目录

一、准备工作

二、所用到的库

1)Numpy:

2)Matplotlib:

3)Pandas:

三、代码实现

1)理科成绩分析.py

2)文理科成绩对比分析.py

四、效果展示


一、准备工作


1)某学校高三文科班一模学生成绩表.csv

2)某学校高三理科班一模学生成绩表.csv

二、所用到的库


1)Numpy:

提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库。专为进行严格的数字处理而产生。

2)Matplotlib:

是一个用来绘图的python库,它的matplotlib.pyplot模块提供了一个与MATLAB非常类似的绘图系统。

3)Pandas:

一个强大的分析结构化数据的工具集;它的使用基础是numpy库,用于数据挖掘和数据分析,同时也提供数据清洗功能。

三、代码实现


1)理科成绩分析.py

# -*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt #绘图
import numpy as np
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
score = pd.read_csv('某学校高三理科班一模学生成绩表.csv',encoding = 'gbk')
total_score=score.总分
num=score.学号
#统计最高分
print("========各项最高分========")
Chinese_Max = score.语文.max()
Math_Max = score.数学.max()
English_Max = score.英语.max()
LiZong_Max=score.理综.max()
total_Max=score.总分.max()
print("语文最高分为{}".format(Chinese_Max))
print("数学最高分为{}".format(Math_Max))
print("英语最高分为{}".format(English_Max))
print("理综最高分为{}".format(LiZong_Max))
print("总分最高分为{}".format(total_Max))
print("========各项最低分========")
Chinese_Min = score.语文.min()
Math_Min = score.数学.min()
English_Min = score.英语.min()
LiZong_Min=score.理综.min()
total_Min=score.总分.min()
print("语文最低分为{}".format(Chinese_Min))
print("数学最低分为{}".format(Math_Min))
print("英语最低分为{}".format(English_Min))
print("理综最低分为{}".format(LiZong_Min))
print("总分最低分为{}".format(total_Min))
##成绩平均值
print("========各项课程平均分========")
Chinese_Avg = score.数学.mean()
Math_Avg = score.数学.mean()
English_Avg = score.英语.mean()
LiZong_Avg = score.理综.mean()
print("语文平均分为{: .1f}".format(Chinese_Avg))
print("数学平均分为{: .1f}".format(Math_Avg))
print("英语平均分为{: .1f}".format(English_Avg))
print("理综平均分为{: .1f}".format(LiZong_Avg))
#成绩方差
print("========各项课程方差========")
Chinese_Var = score.语文.var()
Math_Var = score.数学.var()
English_Var = score.英语.var()
LiZong_Var = score.理综.var()
print("语文成绩的方差为{: .1f}".format(Chinese_Var))
print("数学成绩的方差为{: .1f}".format(Math_Var))
print("英语成绩的方差为{: .1f}".format(English_Var))
print("理综成绩的方差为{: .1f}".format(LiZong_Var))
#画直方图
p1=plt.figure()#创建第一块画布
a1=p1.add_subplot(2,2,1)
plt.title('学生总成绩分布直方图')
plt.xlabel('学号')
plt.ylabel('总分')
plt.bar(num,total_score,color="#78cdd1",label='学生总分')#根据成绩画直方图
max_index=np.argmax(total_score)#最高分的下标
min_index=np.argmin(total_score)#最低分的下标
#标出最高分
plt.plot(max_index+9000,total_score[max_index],'r*',label="最高分")#学号需要加9000
#标出最低分
plt.plot(min_index+9000,total_score[min_index],'g*',label="最低分")#学号需要加9000
plt.legend()
plt.show()

a1=p1.add_subplot(2,2,2)
plt.title('每门课程最高分直方图')
plt.xlabel('课程名')
plt.ylabel('最高分')
plt.bar('语文',Chinese_Max,color='#006c54')
plt.bar('数学',Math_Max,color='#abbc54')
plt.bar('英语',English_Max,color='#aabbcc')
plt.bar('理综',LiZong_Max,color='#09aabb')
plt.show()

a1=p1.add_subplot(2,2,3)
plt.title('每门课程最低分直方图')
plt.xlabel('课程名')
plt.ylabel('最低分')
plt.bar('语文',Chinese_Min,color='#abccdd')
plt.bar('数学',Math_Min,color='#00abc1')
plt.bar('英语',English_Min,color='#ccaa00')
plt.bar('理综',LiZong_Min,color='#00c200')
plt.show()
#画箱线图
p2=plt.figure()#创建第二块画布
b1=p2.add_subplot(2,2,1)
plt.title('每门课程箱线图')
plt.xlabel('课程名')
plt.ylabel('分数')
label = ['语文','数学','英语','理综']
s = (score.语文,score.数学,score.英语,score.理综)
plt.boxplot(s,labels = label)
plt.show()
#画平均分直方图
b1=p2.add_subplot(2,2,2)
plt.title('每门课程平均分直方图')
plt.xlabel('课程名')
plt.ylabel('平均分')
plt.bar('语文',Chinese_Avg,color='#d9d6c3')
plt.bar('数学',Math_Avg,color='#6a6da9')
plt.bar('英语',English_Avg,color='#e0861a')
plt.bar('理综',LiZong_Avg,color='#33a3dc')
plt.show()
#画折线图
b1=p2.add_subplot(2,2,3)
plt.title('学生总成绩分布折线图')
plt.xlabel('学号')
plt.ylabel('总分')
plt.plot(num,total_score,color='#77ac98')
plt.show()
#画散点图
p3=plt.figure()#创建第二块画布
c1=p3.add_subplot(2,2,1)
plt.title('学生总成绩分布散点图')
plt.xlabel('学号')
plt.ylabel('总分')
plt.scatter(num,total_score,color='#d9a6c3')
plt.show()
#画饼图
print("========预测高考上线率========")
lv1=535#一本分数线
lv2=463#二本分数线
lv3=150#专科分数线
A=sum(i>=lv1 for i in total_score) 
B=sum(i>=lv2 and i<lv1 for i in total_score) 
C=sum(i>=lv3 and i<lv2 for i in total_score)
D=sum(i<=lv3 for i in total_score)
print("预测能上一本的有{}人".format(A))
print("预测能上二本的有{}人".format(B))
print("预测能上专科的有{}人".format(C))
print("预测不能上学的有{}人".format(D))
c1=p3.add_subplot(2,2,2)
plt.title('高考上线率预测饼图',size='13')
Labels = '一本','二本','专科','不能上学'
data = [A,B,C,D]
Explode = (0.1, 0.1, 0.1, 0.1,)  
color = ['#b7ba6b', '#deab8a', '#77ac98', '#73b9a2']

plt.pie(data, explode=Explode,labels=Labels,autopct='%.2f%%',colors=color)
plt.show()

print("========总分平均分,标准差========")
#统计标准分
avgs=score.总分.mean()#全体考生的平均分
stds=np.std(score.总分,ddof=1)#总分标准差
print("全体考生的平均分:{}".format(avgs))
print("该次考试分数的标准差:{}".format(stds))
list=score.总分#将所有学生总分放到一个list里面去
#print(list) 
bzfs=[]#存放标准分
for i in list:
    bzf=float((int(i)-avgs)/stds)
    #标准分计算公示 (原始分数-全体考生的平均分)/标准差
    #标准分Z在一般情况下都带小数,而且会出现负值,
    #实际使用时不太方便,所以还要对Z分数进行线性变换(T变换):T=500+100Z
    T=500+100*bzf
    bzfs.append(T)
#print(bzfs) 
#根据标准分绘图
c1=p3.add_subplot(2,2,3)
plt.title('标准分分布图',size='10') 
plt.xlabel('学号')
plt.ylabel('标准分')
plt.plot(num,bzfs,"g.-")
plt.show()
    
    
    
    
    

2)文理科成绩对比分析.py

# -*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt #绘图
import numpy as np
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
#进行文件读取
score = pd.read_csv('某学校高三理科班一模学生成绩表.csv',encoding = 'gbk')
grade = pd.read_csv('某学校高三文科班一模学生成绩表.csv',encoding = 'gbk')
#统计理科最高分
print("****理科成绩各项最高分****")
Chinese_Max1 = score.语文.max()
Math_Max1 = score.数学.max()
English_Max1 = score.英语.max()
LiZong_Max=score.理综.max()
total_Max1=score.总分.max()
print("语文最高分为{}".format(Chinese_Max1))
print("数学最高分为{}".format(Math_Max1))
print("英语最高分为{}".format(English_Max1))
print("理综最高分为{}".format(LiZong_Max))
print("总分最高分为{}".format(total_Max1))
#统计文科最高分
print("****文科成绩各项最高分****")
Chinese_Max2 = grade.语文.max()
Math_Max2 = grade.数学.max()
English_Max2 = grade.英语.max()
WenZong_Max=grade.文综.max()
total_Max2=grade.总分.max()
print("语文最高分为{}".format(Chinese_Max2))
print("数学最高分为{}".format(Math_Max2))
print("英语最高分为{}".format(English_Max2))
print("文综最高分为{}".format(WenZong_Max))
print("总分最高分为{}".format(total_Max2))
#绘图对比
pl=plt.figure()#创建第一块画布
ax1=pl.add_subplot(2,2,1)
Y =[Chinese_Max1,Math_Max1,English_Max1,LiZong_Max,total_Max1]
Y1 =[Chinese_Max2,Math_Max2,English_Max2,WenZong_Max,total_Max2]
X = ['语文', '数学', '英语', '综合', '总分'] #
bar_width = 0.35
index = np.arange(len(Y))
# 绘制「理科各项最高分」的成绩
rects1 = plt.bar(index, Y, bar_width,color='#84bf96',label="理科成绩")
# 绘制「文科各项最高分」的成绩
rects2 = plt.bar(index + bar_width, Y1, bar_width, color='#78cdd1',label="文科成绩")
# X轴数据
plt.xticks(index+0.5*bar_width, X)
# X轴标题
plt.xlabel("各项成绩",color='#2e3a1f',size='10')
# Y轴标题
plt.ylabel("最高分分数",color='#2e3a1f',size='10')
# 图表标题

plt.title("文理科各项成绩最高分对比",color='#2e3a1f',size='14')
# 图例显示在图表下方
plt.legend(loc='upper center', bbox_to_anchor=(0.13, -0.06), fancybox=True, ncol=5)
# 添加数据标签
def add_labels(rects):
    for rect in rects:
        height = rect.get_height()
        plt.text(rect.get_x() + rect.get_width() / 2, height, height, ha='center', va='bottom')
        # 柱形图边缘用白色填充,纯粹为了美观
        rect.set_edgecolor('white')
add_labels(rects1)
add_labels(rects2)
plt.show()
#绘制文理科成绩散点图
total_score1=grade.总分#文科所有人总分成绩
total_score2=score.总分#文科所有人总分成绩
ax1=pl.add_subplot(2,2,2)
plt.title('文理科总成绩分布散点图对比')
plt.xlabel('学号')
plt.ylabel('总分')
num=np.arange(len(total_score1))#用于创建等差数组,这里使用来创建一个存取学号的数组
plt.scatter(num,total_score1,color='#acdd00',label='文科总分成绩')
plt.scatter(num,total_score2,color='#aabbcc',label='理科总分成绩')
plt.legend(loc='upper center', bbox_to_anchor=(0.8, -0.06), fancybox=True, ncol=5)
plt.show()
#统计文理科各分数段的人数
A1=sum(i>=600 for i in total_score1) 
B1=sum(i>=500 and i<600 for i in total_score1) 
C1=sum(i>=400 and i<500 for i in total_score1)
D1=sum(i<400 for i in total_score1)
A2=sum(i>=600 for i in total_score2) 
B2=sum(i>=500 and i<600 for i in total_score2) 
C2=sum(i>=400 and i<500 for i in total_score2)
D2=sum(i<400 for i in total_score2)
x = np.array([D1,C1,B1,A1])#存放文科各分数段的人数
y = np.array([D2,C2,B2,A2])#存放理科各分数段的人数
ax1=pl.add_subplot(2,2,3)
plt.title("文理科各分数段的人数对比",size='14')
rects3=plt.barh(range(len(y)), -x,color='#fedcbd',label='文科')
rects4=plt.barh(range(len(x)), y,color='#00ae9d',label='理科')
plt.xlim((-160,160))
plt.xticks((-150,-100,-50,0,50,100,150),('150','100','50','0','50','100','150'))
plt.yticks((0, 1, 2, 3),('0-400分', '400-500分', '500-600分', '600-750分'))
plt.xlabel('人数(个)')
plt.legend()
plt.show()
#根据当前分数预测文理科学生高考上线率
lv1=535#理科一本分数线
lv2=463#理科二本分数线
lv3=150#理科专科分数线
lv4=547#文科一本分数线
lv5=488#文科二本分数线
lv6=150#文科专科分数线
A_w=sum(i>=lv4 for i in total_score1) 
B_w=sum(i>=lv5 and i<lv4 for i in total_score1) 
C_w=sum(i>=lv6 and i<lv5 for i in total_score1)
A_l=sum(i>=lv1 for i in total_score2) 
B_l=sum(i>=lv2 and i<lv1 for i in total_score2) 
C_l=sum(i>=lv3 and i<lv2 for i in total_score2)
#画折线图
ax1=pl.add_subplot(2,2,4)
plt.title('文理科学生总成绩分布折线图')
plt.xlabel('等级')
plt.ylabel('人数')
xs=['一本','二本','专科']
ys1=[A_w,B_w,C_w]
ys2=[A_l,B_l,C_l]
indexs= np.arange(len(ys1))
plt.plot(indexs,ys1,color='yellow',label='文科')
plt.plot(indexs,ys2,color='red',label='理科')
plt.xticks(indexs+0.5*bar_width,xs)
plt.legend()
plt.show()









四、效果展示


本文介绍的是利用Python语言,做成绩分析并生成成绩分析动态图表。Python语言可以利用Pandas、Pyecharts等各种类库,进行数据分析。 本文介绍的成绩分析大体分为三步: 一、拼合单科成绩,合成学年成绩,计算总分,按总分成绩排名次,然后由学年成绩筛选出各个班级的成绩,将学年成绩,各班级成绩存入一个Excel文件中,工作表分别命名为学年成绩,高三(1)班……等 二、利用生成的第一步生成的Excel文件,做成绩分析,保存成绩分析表格。 三、利用成绩分析表格,做成绩分析动态图。 下面是部分源代码: 1、成绩整理与合并 import glob import os import pandas as pd from functools import reduce inputPath="./原始成绩/" writer_lk = pd.ExcelWriter('./整理后的成绩/2020一模理科总成绩及各班级成绩.xlsx') writer_wk = pd.ExcelWriter('./整理后的成绩/2020一模文科总成绩及各班级成绩.xlsx') inputWorkbook=glob.glob(os.path.join(inputPath,"*.xls")) #====================读取全部学生的所有科目成绩=================================== yw_score = pd.read_excel(inputWorkbook[2]) sxlk_score = pd.read_excel(inputWorkbook[1]) sxwk_score = pd.read_excel(inputWorkbook[0]) yy_score = pd.read_excel(inputWorkbook[5]) yy_score['英语'] = (yy_score['英语'] * 1.25).round(0)#英语成绩不计算听力成绩*1.25 lkzh_score = pd.read_excel(inputWorkbook[4]) wkzh_score = pd.read_excel(inputWorkbook[3]) #======================================================================= #====================整理出理科成绩及分班成绩、计算总分、总分排名、班级排名============================= lk_class = ['高三(1)班','高三(2)班','高三(3)班','高三(4)班'] wk_class = ['高三(5)班','高三(6)班'] lk_yw = yw_score.loc[(yw_score.班级.isin(lk_class)), ['班级','姓名','语文']] lk_sx = sxlk_score[['姓名','数学']] lk_yy = yy_score.loc[(yy_score.班级.isin(lk_class)), ['姓名','英语']] lk_k3 = lkzh_score[['姓名','物理','化学','生物','理综']] lk_list = [lk_yw, lk_sx, lk_yy, lk_k3] score_lk = (reduce(lambda left, right: pd.merge(left, right, on='姓名'), lk_list)) score_lk['总分'] = (score_lk['语文'] + score_lk['数学'] + score_lk['英语'] + score_lk['理综']).round(0) def sort_grade(score): score_sort = score.sort_values(by=['总分'], ascending=False) score_sort['年级排名'] = score_sort['总分'].rank(ascending=0,method='min') return score_sort def sort_class_lk(score_garde,name): class_sort = score_garde.loc[score_garde.班级 == name, :] class_sort = class_sort.sort_values(by=['总分'], ascending=False) class_sort['班级排名'] = class_sort['总分'].rank(ascending=0,method='min') class_sort.to_excel(writer_lk, index=None, sheet_name=name) lk_grade_sort = sort_grade(score_lk) lk_grade_sort.to_excel(writer_lk, index=None, sheet_name='学年成绩') for lk in lk_class: class_sort = sort_class_lk(score_lk, lk) writer_lk.save() writer_lk.close() # #============整理出文科成绩及分班成绩、计算总分、总分排名、班级排名================== wk_yw = yw_score.loc[(yw_score.班级.isin(wk_class)), ['班级','姓名','语文']] wk_sx = sxwk_score[['姓名','数学']] wk_yy = yy_score.loc[(yy_score.班级.isin(wk_class)), ['姓名','英语']] wk_k3 = wkzh_score[['姓名','政治','历史','地理','文综']] wk_list = [wk_yw, wk_sx, wk_yy, wk_k3] score_wk = (reduce(lambda left, right: pd.merge(left, right, on='姓名'), wk_list)) score_wk['总分'] = (score_wk['语文'] + score_wk['数学'] + score_wk['英语'] + score_wk['文综']).round(0) def sort_class_wk(score_garde,name): class_sort = score_garde.loc[score_garde.班级 == name, :] class_sort = class_sort.sort_values(by=['总分'], ascending=False) class_sort['班级排名'] = class_sort['总分'].rank(ascending=0,method='min') class_sort.to_excel(writer_wk, index=None, sheet_name=name) wk_grade_sort = sort_grade(score_wk) wk_grade_sort.to_excel(writer_wk, index=None, sheet_name='学年成绩') for wk in wk_class: class_sort = sort_class_wk(wk_grade_sort, wk) writer_wk.save() writer_wk.close() 2、成绩区间分割与统计 #coding:utf-8 import numpy as np import pandas as pd from functools import reduce fpath_lk="./整理后的成绩/2020一模理科总成绩及各班级成绩.xlsx" fpath_wk="./整理后的成绩/2020一模文科总成绩及各班级成绩.xlsx" writer_lk = pd.ExcelWriter('./整理后的成绩/2020一模理科成绩区间分布统计.xlsx') writer_wk = pd.ExcelWriter('./整理后的成绩/2020一模文科成绩区间分布统计.xlsx') lk = pd.read_excel(fpath_lk, None) #获取表格中的所有工作表的内容 wk = pd.read_excel(fpath_wk, None) #===================1.定义区间分割函数===================================== def cut_750(score_750,len): bins_750= [0,370,380,390,400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580,590,600,620,640,660,750] labels_750 = ['0-370','370-379','380-389','390-399','400-409','410-419','420-429','430-439','440-449','450-459','460-469','470-479','480-489','490-499','500-509','510-519','520-529','530-539','540-549','550-559','560-569','570-579','580-589','590-599','600-619','620-639','640-659','660-750'] cut_750 = pd.cut(score_750, bins_750, labels=labels_750, right=False) qj = pd.DataFrame({'区间':pd.value_counts(cut_750).index,'人数':pd.value_counts(cut_750),'百分比':((pd.value_counts(cut_750))/len).round(3).apply(lambda x: format(x, '.2%'))}).sort_values(by='区间', ascending=False) qj = qj.reset_index(drop=True) return qj def cut_150(score_150,len): bins_150 = [0,30,60,90,120,150] labels_150 = ['0-30', '30-60', '60-90', '90-120', '120-150'] cut_150 = pd.cut(score_150, bins_150, labels=labels_150, right=False) qj = pd.DataFrame({'区间':pd.value_counts(cut_150).index,'人数':pd.value_counts(cut_150),'百分比':((pd.value_counts(cut_150))/len).round(3).apply(lambda x: format(x, '.2%'))}).sort_values(by='区间') 其他源代码及始数据已上传,欢迎各位借鉴,第一次编程,希望网友们能指点不足之处,联系qq:912182988
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值