Pandas数据分析实战——基于北京科技大学计算机2018,2019考研成绩

第一篇博客,主要熟悉一下Pandas的使用,加上本人18年考的北科计算研,就顺手对北科计算机18年,19年的考研成绩做个分析吧,也算给自己学校打个广告吧。 计算机科学与技术是学硕,考数一英一,计算机技术是专硕,考数二英二,政治和专业课题目一样,专业课自主命题。

相关代码和数据请点击此处.
主要涉及到的技术点有:

  1. 读取excel表格
  2. 删除DataFrame行,列
  3. 重命名DataFrame行,列索引
  4. 基于关键词定位DataFrame的行列
  5. 插入新列
  6. 基于Seaborn和DataFrame画图
  7. 基于dict和list新建DataFrame等

主要目的是分析北科计算机近两年的考研动态,对成绩,分数线,报考人数,录取人数,题目难度等分析。

1.数据读取和处理

首先读取两年的考研成绩,都是Excel表

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 读取近两年北京科技大学考研成绩表,以第一栏作为表头
data2019 = pd.read_excel("/home/shaobin/tmp/20190215140202408200.xls", header=1)
data2018 = pd.read_excel("/home/shaobin/tmp/20180203165211753910.xls", header=1)

# 删除考生编号和姓名等敏感信息
data2018.drop(['考生编号', '姓名'], axis=1, inplace=True)
data2019.drop(['考生编号', '姓名'], axis=1, inplace=True)

为了确保数据分析的有效性,我把强军计划或其他学院部分计算机专业的筛掉,只保留北科计通学院,全日制,全国统考,无专项计划的考生,并删去隐私情况。

预览一下表格

2018年计算机技术

avatar

2019年计算机技术

avatar

  可以看出,这两年的表格数据格式是有出入的,不过还好4门成绩的名称和总分的列名没变,省了很大功夫。

接下来,我们就把两年的计算机成绩抽出来,只需要成绩,其他数据都不需要了

cs = pd.DataFrame(data2018_jishu, columns=["政治理论", "外国语", "业务课1", "业务课2","总分"])

  准备将抽出来的2年成绩合并到一个DataFrame表里,就。。。列对列怼上!怼上的同时别忘了插入标签列,不然全混一起了。插入新列并填入相同数据有两种方法

1.在指定位置插入空列,并用fillna函数以指定字符填充NaN当然,也可以先建立有字符的Series,直接插入,不过麻烦了点。

cs.insert(1,'专业名称', pd.Series())
cs.fillna("2018计算机技术", inplace = True)

2.使用reindex函数,将列以列表排序,并指定要插入值,这个主要是麻烦在得将其他列全写出来

cs = cs.reindex(columns=["专业名称","政治理论","外国语","业务课1","业务课2"], fill_value = "2018计算机技术")

最后使用pd.concat函数以相同列名为索引,列对列合并,axis=0是列,axis=1是行

# 将两年的计算机专硕和学硕成绩合在一起,并打标签
cs = pd.concat([rebuild(data2018_kexue, "2018计算机科学与技术"), rebuild(data2018_jishu, 
     "2018计算机技术"),rebuild(data2019_kexue, "2019计算机科学与技术"), rebuild(data2019_jishu, 
     "2019计算机技术"), ], axis=0)

# 重置索引,并把之前的索引删去
cs.reset_index(inplace = True,drop=True)

到此,数据初步成型,但还存在缺考的成绩,得删掉这部分数据

cs_clear = cs[~(cs["外国语"]=="缺考") & ~(cs["政治理论"]=="缺考") & ~(cs["业务课1"]=="缺考") & 
              ~(cs["业务课2"]=="缺考") & ~(cs["政治理论"]=="作弊")]

现在数据终于干净了,让我们再看看数据长啥样

avatar

2.数据数值分析

2.1考研人数增长率

接下来进入正题——数据分析,都说考研热度一直在上升,我们来具体看看情况

  首先使用groupby函数对数据进行简单聚合,统计下考研人数

# 计算机考研人数统计
cs_count = cs.groupby(['专业名称']).size()
# 计算机未弃考人数统计
cs_clear_count = cs_clear.groupby(['专业名称']).size()

  将2018年,2019年报考北科,计算机学硕,计算机专硕的人数还有它们的增长率统计一下,麻烦的地方在于要用dict类型转为Dataframe型格式,使用from_dict函数构造,而且bug的是python字典是无序的,最后的行/列和预期的可能不一样,只能在最后调换一下行/列索引位置

# dict_table是统计数据,count_column是列索引值
dict_table = {"总报考人数":[len(data2018), len(data2019)], 
              "计算机科学与技术报考人数": [cs_count["2018计算机科学与技术"], cs_count["2019计算机科学与技术"]],
              "计算机技术报考人数": [cs_count["2018计算机技术"], cs_count["2019计算机技术"]],
              "计算机科学与技术成绩有效人数": [cs_clear_count["2018计算机科学与技术"], cs_clear_count["2019计算机科学与技术"]],
              "计算机技术成绩有效人数": [cs_clear_count["2018计算机技术"], cs_clear_count["2019计算机技术"]]
             }
count_column = ["2018", "2019"]
growth_count = pd.DataFrame.from_dict(dict_table, orient='index', columns = count_column)

growth_count = growth_count.loc[["总报考人数","计算机科学与技术报考人数", "计算机技术报考人数", "计算机科学与技术成绩有效人数", "计算机技术成绩有效人数"]]

avatar

感觉还不错,现在加上增长率的计算

# 在列末尾新加一列增长率,并输出为百分比形式
growth_count["增长率"] = ((growth_count["2019"] - growth_count["2018"])/growth_count["2018"])
						  .apply(lambda x: '%.2f%%' % (x*100))

avatar

  费劲这么大功夫,我们终于可以得到一些结论了,根据教育部数据,2019年考研报考人数为290万人,比去年增长了52万人,增幅21%。咱们学校的整体上涨率符合大趋势。但对于计算机专业来说,两级分化严重,学硕毛增率11.7%,但净增率只有9.27%(未弃考),还跌了些,而专硕这边报考人数增长恐怖,毛增率达到61.68%,没有放弃考试的比去年多了67.26%。


分析原因,个人认为有三点

  1. 由于人工智能,大数据的火爆,高学历计算机专业越发受追捧,大家考研热情高涨
  2. 加上北科近年计算机专业取得很大的进步,目前QS排名位于全球300-350名次,从2018年7月起计算机学科连续稳居ESI全球排名前1%
  3. 北科在北京一流高校中考研算是比较好考取的学校,导致计算机报考人数整体大幅上涨

至于计算机学硕专硕报考人数差距为什么这么大,我认为有以下原因

  1. 学院研究生招生指标固定,大部分保研同学都选择保学硕,导致学硕招生指标过少,大部分人害怕考不上
  2. 计算机学硕考数学一,英语一,计算机专硕考数学二,英语二,学硕考试难度过大,一般人不敢轻易尝试,从弃考情况也能发现这一点

下文会用数据具体分析

2.2成绩分布

  我们使用df.std(),df.mean(), df.median(), df.max()计算出各科成绩每年的标准差,平均分,中位数和最高分

2018年学硕成绩分析

avatar

2019年学硕成绩分析

avatar

学硕成绩分析

avatar

2018年专硕成绩分析

avatar

2019年专硕成绩分析

avatar

专硕成绩分析 avatar


  整体看,政治和外国语的成绩波动较小,均分,中位数,最高分都只涨了几分,而标准差几乎没变,可见政治和外国语难度降低,区分度减小,对偏理科的计算机考生来说是个好消息。
  两门业务课倒是很有意思,学硕和专硕的成绩走向完全不同,学硕的高数虽然也有不小的提高,但专业课提升更大,平均分提升近10分。而专硕的高数增长简直爆炸,平均分高了17.4分,而中位数提高了24.5分,意味着高数高分端的考生数提升了相当一部分,但专业课起伏不是很大。
  总分上,学硕专硕的成绩都有显著提高,考试难度总体下降不少。


  下面基于成绩频率分布进一步分析,使用seaborn和pandas进行数据可视化绘图,将两年的计算机专硕成绩,计算机学硕成绩分别画在一起,分析考试难度的变化。

  绘图函数如下,使用seaborn对政治成绩进行频率曲线绘制,比较坑的是提取完政治成绩后,Series的标签还是“政治成绩”,只能用rename函数重写标签

sns.kdeplot(cs_clear.loc[cs_clear["专业名称"] == "2018计算机科学与技术"]
            ["政治理论"].rename("2018政治理论"), color="b",shade = True) 
  1. 政治成绩
    avatar

  政治理论的成绩有明显提高,专硕更为明显,可能的原因是专硕复习其他科目压力较小,可以有更多的精力复习政治。

  1. 英语成绩
    avatar

  英语的整体成绩变化不大,学硕的高分明显增多,集中成绩基于没有比变化;专硕集中成绩稍微提高了一点,但占比降低,低分明显增多。

  1. 高数成绩
    avatar

  高数的成绩显著提高,果然应了张宇老师说的话,“19级的同学要感谢18级学长学姐的付出,你们的高分是他们用眼泪换来的!”,记得我当时考高数的时候真的写懵了,线代部分题刁钻的无从下笔,是无从下笔,是感觉完全没见过,是能搞崩心态的那种怪题!感觉整个人都凉了,19年的数学看来是恢复常规了。数学考奇不考偶,今年考研的同学得注意加强高数的复习了!

  1. 专业课成绩
    avatar

  专业课的成绩也有了明显提高,并且还是保持两极分化,整体往右平移了一格。专业课初试考数据结构和计算机组成原理,都不是特别难。但从17年考研开始,专业课改了题型,19年考生有17年,18年两次考研题型参考,对考研成绩帮助还是很大的,今年复试加入了上机编程,对考生的要求又提高了不少。

  1. 总分
    avatar

      总分上来看,19年计算机学硕,专硕成绩都有不小的提高,特别是400以上的考生多了不上。从图像上看,19年考研的成绩显著提升,竞争无疑也提高了不少。

  再来分析一下各科目过线率的情况

  2018年的国家线是34分(100满分)和51分(150满分),总分是260分,录取线学硕是314分,专硕是318分。

  2019年是39分(100满分)和59分(150满分),总分是270分,录取线学硕是340分,专硕是361分。

  虽然国家线离专业录取线还有很大一截,但过线率还是能衡量一下考生素质和考试难度的,而且只有过了国家线才能参与调剂,所以各位想读研的小伙伴还是得注意一下国家线是多少,才好指定复习计划。

学硕过线统情况avatar专硕过线统情况avatar

  这里的过线率是用总报考人数计算的,没有去掉缺考的人数。

  实际上,虽然考试难度降低了,除了专硕的高数上涨不少,其他科目的过线率不升反降,可以看的出整体考生的素质是有所降低的,所以大家不要被猛增的报考人数吓到了,很大一部分考生是抱着“两日游”的心态来考研的,只要认真复习,积极备战,大家一定会有所收获。

最后说一下报录比的情况
avatar

avatar

  为了方便观察,给出两种比例方式。19年计算机学硕的竞争减小,而19计算机专硕的竞争相当激烈。值得一提的是,19年的招生指标变多了,复试易进难出,看的出来学院对考生的综合素质有更多要求,符合研究生的灵活科研,不再是应试学习。

3.结论

  很多小伙伴已经在积极备战20年考研了,现在英语和政治的出题风格求稳,起伏不大。但数学和专业课得引起大家的重视,特别是19年的高数难度降低,20年肯定会出有区分度的题。希望各位小伙伴认真对待哦,不过作为考研的过来人,我觉得不放弃才是最重要的,只要不弃考,一定能对的起自己的付出。

  北科计算机专硕学硕差别不大,学硕可以硕博连读,而什么学费,培养计划是一样,专硕复习的范围相对较少,但竞争还是比较激烈的,大家根据自己的具体情况报考。

  北科的计算机综合实力还是不错的,大家可以尝试哦,欢迎大家报考北科计算机!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
本文介绍的是利用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
Pandas是一个开源的数据分析库,提供了高效的数据结构和数据分析工具。它是基于NumPy构建的,可以处理各种类型的数据,包括结构化的数据和时间序列数据。 在进行Pandas数据分析实战时,你可以按照以下步骤进行: 1. 导入Pandas库:在开始之前,需要导入Pandas库。你可以使用以下代码导入Pandas: ```python import pandas as pd ``` 2. 读取数据:使用Pandas的`read_csv()`函数读取数据文件。例如,如果你的数据文件是一个CSV文件,你可以使用以下代码读取: ```python data = pd.read_csv('data.csv') ``` 3. 数据探索:使用Pandas的各种函数和方法来探索数据。你可以使用以下代码查看数据的前几行: ```python data.head() ``` 4. 数据清洗:清洗数据是数据分析的重要步骤之一。你可以使用Pandas的函数和方法来处理缺失值、重复值等。例如,使用以下代码删除重复值: ```python data = data.drop_duplicates() ``` 5. 数据分析:使用Pandas的函数和方法进行数据分析。你可以使用各种统计函数、聚合函数和可视化工具来分析数据。例如,使用以下代码计算某一列的平均值: ```python mean_value = data['column_name'].mean() ``` 6. 数据可视化:使用Pandas和其他可视化库(如Matplotlib和Seaborn)来可视化数据。你可以使用各种图表和图形来展示数据的特征和趋势。例如,使用以下代码绘制柱状图: ```python import matplotlib.pyplot as plt data['column_name'].plot(kind='bar') plt.show() ``` 这些是进行Pandas数据分析实战的基本步骤。当然,具体的分析任务可能会有所不同,你可以根据自己的需求和数据特点进行相应的操作和分析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值