目录
一.训练要点
掌握使用seaborn库或者matplotlib库进行数据可视化的方法
掌握撰写可视化分析报告的方法
二.需求说明
在现实生活中,学生的成绩与表现往往受制于多方面的因素。在教学研究中,除去对各科目考试结果本身的分析外,如果能够深入地对学生其他信息(如对学生家庭背景、性别、饮食、课前准备等影响因素)进行分析,那么老师将会进一步了解学生在考试中的表现。学生考试成绩数据集中包含8各字段,共计1000条数据,其字段信息说明如下表所示。
表:学生考试成绩数据集中的字段信息说明
字段名称 | 字段含义 | 示例 |
性别 | 学生的性别、包括女、男 | 女 |
民族 | 学生所属的民族,包括A、B、C、D、其他 | A |
父母受教育程度 | 父母受教育程度,包括硕士学位、学士学位、大学未毕业、副学士学位、高中毕业、高中未毕业 | 硕士学位 |
午餐 | 学生所用午餐的标准,包括标准、免费 | 标准 |
课程完成情况 | 前置课程完成情况,包括完成、未完成 | 完成 |
数学成绩 | 数学成绩,满分为100分 | 69 |
阅读成绩 | 阅读成绩,满分为100分 | 90 |
写作成绩 | 写作成绩,满分为100分 | 80 |
为了了解不同性别的学生在数学、阅读、写作中的表现,了解父母受教育程度对学生数学、阅读、写作是否有影响,了解午餐标准对学生成绩是否有影响,了解考试准备充分是否有助于提高学生成绩,需要对学生考试成绩数据集进行数据读取、处理、可视化分析。
三.实验步骤
1.使用Pandas库读取文件,查看原始数据的相关特征和描述信息,检查是否有空值。
可以看出,数据集共有1000条记录,每条记录包含了8个字段,数据类型包括了字符串和整数型,且每个字段均无空值。
2.分别获取数据框中的阅读成绩、数学成绩、写作成绩3个字段,累加求和计算出每个学生的总分total_score,再除以3得到平均分percentage。
这段代码向数据框中添加了两行新的代码,分别是总分total_score和平均分percentage。
3.设置各门课程及格线为60分,分别判断学生是否通过(Fail/Pass)每门课,合并新的数据列pass_reading、pass_math、pass_writing。
首先定义一个用于判断是否合格的函数,然后使用Pandas的apply方法,利用is_pass函数判断学生是否通过三门课程,将判断结果累加到新列pass_reading、pass_math、pass_writing中。
4.判断每个学生的整体状态是否通过。如果3门课中有一门为Fail,则最后考核为Fail,合并新的数据列status。
首先定义一个用于判断学生整体状态的函数,然后使用Pandas的apply方法,利用is_overall_pass函数判断学生整体状态是否通过,并将结果累加到新列status中。
5.对于总分是Pass的数据,根据平均分设置5级制成绩,即percentage大于等于90分为优秀,80~89分为良好,70~79分为中等,60~69分为几个,其他为不及格。
首先定义一个用于评定5级制成绩的函数,然后使用Pandas的apply方法,利用grade函数评定每个学生在考试中的成绩等级,并将结果累加到新列grade中。
6.绘制可视化图形,具体操作如下。
(1)绘制父母受教育程度的水平柱状图
以下代码生成了一个水平柱状图,用于表示不同教育水平的父母数量。
(2)绘制全体学生成绩分布饼图
以下代码生成了一个饼图,用于表示全体学生在考试中的成绩情况分布。
(3)绘制各科成绩分布直方图
以下代码生成了一个直方图,用于表示各科成绩的分布情况。
(4)绘制父母受教育程度与前置课程是否完成统计分类图
以下代码生成了一个统计分类图,用于表示不同教育水平的父母和孩子是否完成前置课程的数量关系。
(5)绘制成绩评级与性别分布箱线图
以下代码生成了一个箱线图,用于表示不同性别学生在不同成绩等级下的平均分分布情况。
(6)绘制午餐标准与总成绩的性别分类散点图
以下代码生成了一个散点图,用于表示不同午餐标准和性别学生在总成绩和平均分上的分布情况。
(7)绘制各特征的相关热力图
以下代码生成了一个热力图,用于表示不同字段之间的相关性。图中颜色越红表示相关度越高,蓝色则表示相关度较低
四.代码总览
import pandas as pd # 读取数据集文件 df = pd.read_csv("StudentsPerformance.csv", encoding="gbk") # 查看数据集信息 #print(df.info()) # 计算总分和平均分 df['total_score'] = df[['阅读成绩', '数学成绩', '写作成绩']].sum(axis=1) df['percentage'] = df['total_score'].apply(lambda x: round(x / 3, 2)) #print(df[['阅读成绩', '数学成绩', '写作成绩', 'total_score', 'percentage']].head()) def is_pass(score): if score >= 60: return 'Pass' else: return 'Fail' # 判断学生是否通过每门课程 df['pass_reading'] = df['阅读成绩'].apply(is_pass) df['pass_math'] = df['数学成绩'].apply(is_pass) df['pass_writing'] = df['写作成绩'].apply(is_pass) def is_overall_pass(row): if row['pass_reading'] == 'Fail' or row['pass_math'] == 'Fail' or row['pass_writing'] == 'Fail': return 'Fail' else: return 'Pass' # 判断学生整体状态是否通过 df['status'] = df.apply(is_overall_pass, axis=1) def grade(percentage): if percentage >= 90: return 'Excellent' elif percentage >= 80: return 'Good' elif percentage >= 70: return 'Medium' elif percentage >= 60: return 'Pass' else: return 'Fail' # 设置5级制成绩 df['grade'] = df['percentage'].apply(grade) print(df.head()) import seaborn as sns import matplotlib.pyplot as plt # 指定字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # # 绘制父母受教育程度的水平柱状图 # sns.countplot(x='父母教育程度', data=df) # plt.title('父母受教育程度的水平柱状图') # plt.xlabel('父母教育程度') # plt.ylabel('人数') # plt.show() # # 绘制全体学生成绩分布饼图 # df['grade'].value_counts().plot(kind='pie', autopct='%1.1f%%') # plt.title('全体学生成绩分布饼图') # plt.show() # # 绘制各科成绩分布直方图 # plt.hist(df['数学成绩'], bins=20, alpha=0.5, label='数学成绩') # plt.hist(df['阅读成绩'], bins=20, alpha=0.5, label='阅读成绩') # plt.hist(df['写作成绩'], bins=20, alpha=0.5, label='写作成绩') # plt.xlabel('成绩') # plt.ylabel('人数') # plt.legend(loc='best') # plt.show() # # 绘制父母受教育程度与前置课程是否完成统计分类图 # sns.countplot(x='父母教育程度', data=df, hue='课程完成情况') # plt.title('父母受教育程度与前置课程是否完成统计分类图') # plt.xlabel('父母教育水平') # plt.ylabel('人数') # plt.show() # # 绘制成绩评级与性别分布箱线图 # sns.boxplot(x='性别', y='percentage', data=df, hue='性别') # plt.title('成绩评级与性别分布箱线图') # plt.xlabel('性别') # plt.ylabel('Percentage') # plt.show() # # 绘制午餐标准与总成绩的性别分类散点图 # sns.scatterplot(x='total_score', y='percentage', data=df, hue='午餐', style='性别') # plt.title('午餐标准与总成绩的性别分类') # plt.xlabel('Total Score') # plt.ylabel('Percentage') # plt.show() # # 绘制各特征的相关热力图 # sns.heatmap(df.corr(), annot=True, cmap='coolwarm') # plt.title('各特征的相关热力图') # plt.show()