Python3分析考试成绩1成绩预处理

1.数据预处理

首先用Excel内部的VLOOKUP函数,将每位学生的成绩匹配。这里最好还是用身份证号或者学籍号进行匹配,一方面准确,不易出现重名、字符编码之类的问题,另一方面有利于保护学生数据隐私。

 

像一些学生因特殊原因没有成绩,一种处理方法是寻找类似变化的成绩进行替代,另一种是,如果缺失成绩过多,就将整行成绩去掉。可以考虑中间缺失值,用前后均值替代。值也可以考虑用之前的均值和之后均值的差,来填充这个差值,这个前后均值,可以考虑选取之前与缺失数据比较接近的程度的均值。使用相似样本的均值添补缺失值,或者考虑用机器学习的方法预测缺失值。但是如刚才所说,缺失成绩过多,则应删掉,也就是如果一共6项成绩,有4项缺失,则必须要删掉了。接下来,我们尝试用这样一种顺序来做相应数据的清洗:删除缺失过多的数据--对缺失数据进行填充--导出新的Excel。

1. 删除缺失过多的数据  2. 对缺失数据进行填充

import pandas as pd
tablePath = '1化学数据清洗.xls'

#导入测试的xls数据,并DataFrame化
originalData = pd.DataFrame(pd.read_excel(tablePath))   #导入excel数据,并转化为DataFrame格式
#print(originalData)
delDoneData = originalData.dropna(axis=0,thresh=5) #每行至少保留5个数据,也就是除了班级、姓名之外,还得有3个非空值数据,否则将删除整行
sortData = delDoneData.sort_values(by=['化学2'],ascending=False)                     #按第2列进行排序
sortData = sortData.reset_index(drop = True)        #重置索引
print(sortData)
sortData = sortData.interpolate(method='akima')   #用method= 改变参数,进行插值
print(sortData)
sortData.to_excel('1.xls')

 

 

 

Pandas 中的插值,通过 interpolate() 方法完成,默认为线性插值,即 method='linear'。除此之外,还有{‘linear’, ‘time’, ‘index’, ‘values’, ‘nearest’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘barycentric’, ‘krogh’, ‘polynomial’, ‘spline’, ‘piecewise_polynomial’, ‘from_derivatives’, ‘pchip’, ‘akima’}等插值方法可供选择。那么接下来,我们就对这些方法进行逐一比较。比较的数据,集中在几个典型的缺失数据上。

 

 

 

 

 

 

从图中可以看出,第一个系列,liner、pchip、akima方法得出的数据比较符合规律。第二个是liner、quadratic较为符合。注意图4,数据匹配过高,与后面几次数据的符合度较差,所以要进行手动修正。

这种插值方法,比较简单基础,也是比较符合实际,但是还是要根据学生具体的情况,来确定其合理的数值。

最后我们得到了数据清洗之后的成绩总表,用于使用Excel和各种方法进行导入并分析。

3. 观察数据特点

 

 

从图中、以及标准差可以看出,第一次的数据与后面各项数据偏差太大,所以后面分析的时候,可以考虑删除。

至此,数据的预处理到此为止。如果是用于建立模型,并使用得到的结果进行预测,最好还是删除所有空值及0的行,这样预测得到的结果可能更具有代表性。

参考资料:

参考资料:https://blog.csdn.net/lwgkzl/article/details/80948548

https://blog.csdn.net/oxuzhenyi/article/details/77971330


接下来要做的,是用Excel的各种图表分析工具,对这些数据进行逐类分析,力图从基础指标得到一些能够帮助学生确定自身努力方向的结果。

本文介绍的是利用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
发出的红包

打赏作者

limaning

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值