Python数据分析实战:利用Pandas与Matplotlib解析学校四六级成绩

凌晨两点半
凌晨两点半
发布时间:2026-10-13 | 3人浏览过
原创

本文基于Python的Pandas和Matplotlib库,对某学校近9000条四六级考试成绩进行清洗与分析。通过数据预处理、分组统计及可视化绘图,展示了各学院平均分、过关人数分布及男女生通过率差异,为教育数据分析提供完整代码示例与结果解读。

近期深入学习了数据分析相关领域,初步掌握了Python中numpy和pandas的基础用法。为了避免技能生疏,我决定通过实际操作来巩固所学。恰好之前社群分享了一份学校四六级成绩表,这便成为了我熟悉pandas各项功能的绝佳素材。

1. 数据概况说明。

原始成绩表字段详尽,涵盖年级、性别、姓名、分数等大量信息。鉴于本次分析仅聚焦于学校整体的四六级通过率,因此剔除无关字段,保留核心数据如下:

第一列为自增序号,无实际分析价值。

第二列标识学生参加的是四级(CET-4)还是六级(CET-6)考试。

第三列记录学生所属的院系名称。

第四列显示学生所在的具体专业。

第五列为年级字段,其中“13”代表2013年入学。

第六列为性别信息。

后续三列分别对应总分、听力分数及阅读分数(注:原文提及写作,但代码仅处理总分,此处依原文描述保留)。

总分为0的记录视为缺考。数据集中包含近9000条有效记录(未报名者未计入)。

2. 预期分析目标。

计划通过图表直观展示以下关键指标:

1. 各学院四六级考试的平均分数。

2. 各学院四六级考试的通过人数。

3. 各学院各年级的通过人数分布。

4. 各年级整体的通过人数。

5. 男生与女生各自的通过人数对比。

最终输出结果如下:

各学院四六级通过人数统计:

3. 具体实现步骤。

(1)导入必要依赖库。

程序主要使用pandas进行数据分组与转换,并调用matplotlib实现绘图功能。

import pandas as pd
import matplotlib.pylab as plt

(2)加载数据文件。

分析数据需先获取源数据,我将整理后的数据保存为sj.xls(Excel格式)。 此步骤通过pandas的read_excel函数读取,生成DataFrame对象。

#加载全部数据
sj = pd.read_excel(r'F:\DataAnalysis\sj.xls')

加载完成后,输出查看数据内容:

除排版未对齐外,数据结构与预期一致。

(3)统计各学院平均分。

此处实现第一个预期目标:

各学院四六级平均分统计:

需按“院系名称”分组,并区分“CET4”和“CET6”两组。使用groupby生成SeriesGroupBy对象,再调用mean函数(默认沿轴0计算,即符合需求)即可得出平均分。

#按照各个学院进行分组
xymean = sj['总分'].groupby([sj['院系名称'],sj['语言级别']])

#计算各个学院的平均分数
xymean = xymean.mean()

直接输出结果如下:

由于院系名称和语言级别构成层次化索引,显示效果不够直观,因此使用unstack将语言级别从行索引转换为列索引。

xymean = xymean.unstack(level='语言级别')

再次输出,结果结构更为清晰:

利用pandas内置绘图功能生成图表:

#使用横向柱状图显示
xymean.plot(kind='barh')

#在PyCharm中需要使用,在Ipython环境中如果以--pylab形式打开就不需要
plt.show()

运行代码查看效果:

数据显示正常,但中文显示出现乱码问题。经查阅相关社区讨论(如seaborn issue #1009)可解决:

添加以下配置代码即可:

import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['font.serif'] = ['SimHei']

再次运行,中文显示恢复正常。

接下来进行通过情况的深入分析。

(4)数据筛选。

在拥有全量数据后,下一步是筛选出所有通过考试的学生记录。

#过滤出过关人数
sjpass = sj[sj['总分'] >= 425]

此时sjpass变量存储了所有通过考试的数据。

在输出结果末尾可见共有1507行通过记录,也可通过len()或shape[0]方法验证行数。

(5)各学院四六级通过人数统计。

基于通过数据,按预期目标分组。同样依据“院系名称”和“语言级别”对总分进行分组,使用count函数统计人数,最后通过unstack调整结构并绘图展示。

#按照各个学院进行分组
xypass = sjpass['总分'].groupby([sjpass['院系名称'],sjpass['语言级别']])


#计算各个学院的过关总人数
xypass = xypass.count()

#将语言级别作为columns
xypass = xypass.unstack(level='语言级别')

#进行绘图
xypass.plot(kind='barh')
plt.show()

绘图结果如下:

(6)各学院各年级通过人数统计。

此次分组增加“年级”维度。为优化图表美观度,将“年级”转换为列,并对如12年级等无人参考的缺失值用0填充:

#按照各个学院和年级进行分组
xypass = sjpass['总分'].groupby([sjpass['院系名称'],sjpass['语言级别'],sjpass['年级']])

#计算各个学院的过关总人数
xypass = xypass.count()

#将语言级别作为columns,并且将缺失值用0进行填充
xypass = xypass.unstack(level='年级').fillna(0)

xypass.plot(kind='barh')
plt.show()

绘图结果如下:

(7)各年级通过人数统计。

直接对年级进行groupby分组:

#-----------------各个年级过关人数------------------
njpass = sjpass['总分'].groupby([sjpass['年级'],sjpass['语言级别']]).count().unstack(level='语言级别')
njpass.plot(kind='barh')
plt.show()

绘图结果如下:

(8)男女生通过人数对比。

对性别和语言级别进行分组统计:

#---------------男生女生过关情况----------------------
nvpass = sjpass['总分'].groupby([sjpass['性别'],sjpass['语言级别']]).count().unstack(level='语言级别')
nvpass.plot(kind='bar')
plt.show()

绘图结果如下:

4. 结果分析与讨论。

从图表结果来看,各学院间存在差异:音乐学院平均分较低,而艺术设计和外国语学院的平均分较高,但其通过人数相对较少,尤其是艺术设计学院,主要受限于该院总人数较少。

四级通过人数显著多于六级。由于我校规定大二方可参加四六级考试,15级学生(大二)在通过人数中占比较大。

此外,数据显示女生的通过率明显高于男生。

完整源码及数据链接:https://github.com/jiajia0/DataAnalysis

本文内容到此结束,希望能为各位的学习提供参考,欢迎继续支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表