Python实战:深度分析学生成绩数据,洞悉其背后的规律与趋势

  在教育领域,对学生成绩进行深入分析能够为教学改进、学生辅导等提供有力依据。本文将使用 Python 中的pandasmatplotlib库,对学生成绩数据进行读取、清洗、分析和可视化,带你一步步探索数据背后的信息。

一、数据读取与合并

  首先,我们需要读取两份学生成绩数据文件ReportCard1.txtReportCard2.txt。这两份文件分别记录了学生的不同科目成绩,通过学生学号xh进行关联:

部分数据如下:

 

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

# 设置中文字体
matplotlib.rcParams['font.family'] = 'SimHei'
# 解决负号显示问题
matplotlib.rcParams['axes.unicode_minus'] = False

# 读取数据文件
try:
    df1 = pd.read_csv('ReportCard1.txt', sep='\t', na_values=['NA', 'NaN'])
    df2 = pd.read_csv('ReportCard2.txt', sep='\t', na_values=['NA', 'NaN'])
except FileNotFoundError:
    print("错误:未找到数据文件,请检查文件路径和文件名。")
    exit(1)

# 合并数据
merged_df = pd.merge(df1, df2, on='xh', how='inner')
merged_df.to_excel('merged_student_grades.xlsx', index=False)

 

  在这段代码中,pd.read_csv函数用于读取数据文件,sep='\t'表示文件以制表符分隔,na_values=['NA', 'NaN']用于指定将文件中的NANaN识别为缺失值。通过pd.merge函数,根据学号xh将两份数据进行内连接合并,并将合并后的数据保存为merged_student_grades.xlsx文件。 

 

二、数据清洗与预处理 

  数据中可能存在缺失值,为了后续分析的准确性,我们将缺失值填充为 0。同时,计算每个学生的总成绩和平均成绩,并按总成绩进行降序排序:

# 填充缺失值为0
merged_df.fillna(0, inplace=True)

# 计算总成绩
merged_df['total_score'] = merged_df.drop(['xh','sex'], axis=1).sum(axis=1)

# 计算平均成绩
merged_df['average_score'] = merged_df['total_score'] / 8

# 将数据按总成绩的降序排序
sorted_df = merged_df.sort_values('total_score', ascending=False)

  fillna(0, inplace=True)方法将缺失值替换为 0。计算总成绩时,使用drop方法排除学号和性别列,再通过sum(axis=1)按行求和。平均成绩则是总成绩除以科目数 8。最后,使用sort_values方法按总成绩降序排列数据。 

 

三、数据分析 

1.按性别计算课程平均成绩

  我们可以通过分组操作,按性别分别计算各门课程的平均成绩,了解不同性别学生在各科目上的表现差异:

# 按性别分别计算各门课程的平均成绩
gender_avg = merged_df.groupby('sex').mean()

  groupby('sex').mean()方法按性别分组,并计算每组的平均值,得到不同性别学生在各科目上的平均成绩。 

2.成绩等级划分与统计

  为了更直观地评估学生成绩,我们将平均成绩划分为优、良、中、及格和不及格五个等级,并统计各等级的人数:

# 按优、良、中、及格和不及格,对平均成绩进行分组
def grade(score):
    if score >= 90:
        return '优'
    elif 80 <= score < 90:
        return '良'
    elif 70 <= score < 80:
        return '中'
    elif 60 <= score < 70:
        return '及格'
    else:
        return '不及格'

merged_df['grade'] = merged_df['average_score'].apply(grade)

# 检查成绩等级的数据类型
if not pd.api.types.is_string_dtype(merged_df['grade']):
    merged_df['grade'] = merged_df['grade'].astype(str)

# 检查成绩等级分布
grade_distribution = merged_df['grade'].value_counts()
print("成绩等级分布:")
print(grade_distribution)

# 按性别统计优、良、中、及格和不及格的人数
gender_grade_counts = merged_df.groupby(['sex', 'grade']).size().unstack(fill_value=0)

  定义grade函数进行成绩等级划分,使用apply方法将该函数应用到平均成绩列,生成成绩等级列grade。通过value_counts方法统计各等级人数,groupby(['sex', 'grade']).size().unstack(fill_value=0)按性别和成绩等级统计人数并整理成表格形式。 

 

四、数据可视化 

1.总成绩直方图

  绘制总成绩的直方图,能够直观展示总成绩的分布情况:

# 绘制总成绩的直方图
plt.figure(figsize=(10, 6))
plt.hist(merged_df['total_score'], bins=10, edgecolor='black')
plt.title('总成绩直方图')
plt.xlabel('总成绩')
plt.ylabel('频数')
plt.show()

plt.hist函数用于绘制直方图,bins=10指定直方图的组数为 10,edgecolor='black'设置直方图边框颜色为黑色。 

 

2.平均成绩等级饼图 

  通过饼图展示平均成绩的等级分布,能更清晰地看出各等级在总体中所占比例:

# 绘制平均成绩的优、良、中、及格和不及格的饼图
grades = merged_df['grade'].value_counts()
print("统计的各等级数量:", grades)

labels = grades.index
print("生成的标签:", labels)

if len(labels) == 0:
    print("警告:未生成有效的标签,请检查数据处理过程。")
else:
    plt.figure(figsize=(8, 8))
    # 绘制饼图,确保标签显示,并调整标签位置
    patches, texts, autotexts = plt.pie(
        grades, 
        labels=labels, 
        startangle=90, 
        labeldistance=1.05,  
        autopct='%1.1f%%',  
        colors=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'],  
        textprops={'fontsize': 12, 'color': 'black'}  
    )
    for text in texts:
        text.set_visible(True)  
    for autotext in autotexts:
        autotext.set_color('black')  
        autotext.set_fontsize(10)  
    plt.title('平均成绩等级分布')
    plt.axis('equal')  
    plt.legend(labels, loc="best")  
    plt.show()

  获取各等级人数后,使用plt.pie函数绘制饼图。设置startangle=90使饼图从 90 度开始绘制,labeldistance=1.05调整标签位置,autopct='%1.1f%%'显示百分比,还可设置颜色和标签字体等属性。 

 

3.总成绩与数学成绩散点图 

  绘制总成绩和数学成绩的散点图,可以观察两者之间的相关性。 plt.scatter函数绘制散点图,alpha=0.6设置点的透明度,便于观察点的分布情况:

# 绘制总成绩和数学(math)成绩的散点图
plt.figure(figsize=(10, 6))
plt.scatter(merged_df['total_score'], merged_df['math'], alpha=0.6)
plt.title('总成绩与数学成绩散点图')
plt.xlabel('总成绩')
plt.ylabel('数学成绩')
plt.show()

 

(1)整体趋势与数据分布范围

  从散点的分布来看,大致呈现出一种从左下到右上的趋势。这表明总成绩和数学成绩之间存在正相关关系,即一般情况下,学生的总成绩越高,其数学成绩往往也越高 。从横坐标可以看出,总成绩的范围大致在 350 到 650 左右。其中,大部分数据集中在 500 – 600 之间,说明多数学生的总成绩集中在这个区间。从纵坐标来看,数学成绩的范围大致在 0 到 85 左右。多数学生的数学成绩集中在 40 – 80 之间,说明这个区间是学生数学成绩的主要分布范围。

(2)异常值分析

  在散点图左下角有个别点,其总成绩和数学成绩都相对较低,这些点代表的学生可能在学习上存在较大困难,需要特别关注和辅导。 图中存在一些相对孤立的点,例如有一个点总成绩在 400 左右但数学成绩接近 0,可能存在特殊情况,如考试发挥失常等。

五、总结 

  通过以上步骤,我们完成了从数据读取、清洗、分析到可视化的全过程。利用pandasmatplotlib库,我们对学生成绩数据进行了全面深入的分析,通过各种图表直观地展示了数据特征和规律。这不仅帮助我们了解学生的学习情况,也为教育工作者提供了有价值的参考,以便做出更合理的教学决策。希望本文能对你在数据分析实践中有所帮助,大家可以根据实际需求进一步优化和扩展代码,探索更多有趣的数据信息。

作者:#guiyin11

物联沃分享整理
物联沃-IOTWORD物联网 » Python实战:深度分析学生成绩数据,洞悉其背后的规律与趋势

发表回复