目录
一、准备工作
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()