用实践带领你进入numpy的世界——(六):numpy综合小练习①

                         QQ:3020889729                                                                                 小蔡

特别声明

这是一个简单的学生成绩问题,以促进对numpy的认识、理解和运用。
本练习采用jupyter notebook运行,所以,如果是采用其它如pycharm的ide,需要将上一个任务需要的数据进行剪切才能正常运行。
jupyter notebook可以从上而下依次运行

练习内容

  1. lambda关键字
  2. np.random.randint生成随机整数
  3. np.random.rand生成随机0~1的数
  4. np.round四舍五入保留小数位
  5. np.unique元素去重
  6. np.max取最大值
  7. narray.tolist(),np的narray对象转list数据对象
  8. np.mean取平均值
  9. np.flip反转数组
  10. np.sum求和
  11. plt.bar绘制条形图
  12. plt.pie绘制饼图

练习任务

目标 任务内容
任务一 获取所有学生成绩中,每一科目中出现过的分数(因为可能有分数相同,但是只出一次),每一科目的单科成绩排名以及最高分
3.任务二 每个学生的平均分排名以及获取平均分最高分学生序号——学生平均分成绩排名
4.任务三 绘制20个同学的平均成绩条形图
4.任务四 计算及格率,以及绘制及格所占的饼状图

开始练习


导入必要的库

import numpy as np
import matplotlib
from matplotlib import pyplot as plt

matplotlib.rcParams['font.sans-serif'] = ['SimHei']  # 设置绘图字体
matplotlib.rcParams['axes.unicode_minus'] = False  # 设置符号(负号的正常显示)

数据准备

1.随机生成20个学生的成绩:每个学生成绩包含语、数、外、物、化、生、体的成绩。

# 成绩:20*7
students_num = 20  # 学生人数
course_num = 7     # 成绩科目数
# 成绩组成:int + float(保留1位小数)
student_scores_int = np.random.randint(40, 100, (20, 7))   # 成绩组成,整数部分
student_scores_float = np.random.rand(20, 7)             # 成绩组成,小数部分
student_scores = np.round(student_scores_int + student_scores_float, 1) # np.round 保留一位小数
print("生成的学生成绩表(20*7)如下:\n\n", student_scores)

结果展示:(由于是随机数参数,所以每一次运行出来的成绩可能不相同)

在这里插入图片描述


任务一

2.任务一:获取所有学生成绩中,每一科目中出现过的分数(因为可能有分数相同,但是只出一次),每一科目的单科成绩排名以及最高分

# 获取每一个科目出现过的分数(使用np.unique)
course_lib_get = lambda x, y: x[:, y]
course_name = ['Chinese', 'Math', 'English', 'Biologic', 'Chemistry', 'Physics', 'Sports'] # 字典列表
course_scores_dict = {course_name[x]:[] for x in range(7)}  # 存储每一科的成绩
course_first = {course_name[x]:[] for x in range(7)}  # 存储每一科的最好成绩
for i in range(len(student_scores[1,:])):  # len对于维度的长度计算,默认是axis==0的轴,也可以通过切片等操作实现更进一维长度的计算
    course_scores = course_lib_get(student_scores, i)  # 依次获取科目的成绩
    course_scores = np.unique(course_scores)  # 去掉每一科中重复出现的分数(np.unique,处理一维去重自动排序)
    course_scores_dict[course_name[i]] = course_scores.tolist()    # 以字典方式存储,tolist()转换为字典
    course_first[course_name[i]] = np.max(course_scores).tolist()  # 以字典方式存储每一科的最高分
    
print("科目最高分:\n{0}\n\n".format(course_first))

print("\n本次考试每一科出现过的成绩:")
for n in course_scores_dict:  # 遍历字典的key
    print("{0}:\n {1}\n".format(n, course_scores_dict[n]))

结果展示:

在这里插入图片描述


任务二

3.任务二:每个学生的平均分排名以及获取平均分最高分学生序号——学生平均分成绩排名

# 获取每个学生的平均分排名以及每一科目的单科成绩排名——并获取相应学生的序号
students_mean = np.mean(student_scores, axis=1).round(1)  # 以行计算平均,保留1位小数
# students_mean
student_mean_index = {students_mean[x]:x for x in range(20)}  # 为平均分打上所属编号:学生编号
student_mean_rank = {student_mean_index[x]:x  for x in np.flip(np.sort(students_mean))}  # 获取平均分排名
print("学生平均分成绩排名:")
rank_index = 1
for x in student_mean_rank:
    print('第{0}名:[{1}: {2}]'.format(rank_index, x, student_mean_rank[x]))
    rank_index += 1

结果展示:
在这里插入图片描述


任务三

4.任务三:绘制20个同学的平均成绩条形图

bar_height = students_mean.tolist()  # 获取平均成绩的list
x_label = [i for i in range(0, 200, 10)]  # 配置条形图的位置参数(以及条形间隔)
Total_mean = np.sum(students_mean)/20  # 总学生平均成绩
Total_mean_bar_height = [Total_mean for i in range(20)]  # 扩展总学生平均成绩为list

rects1 = plt.bar(x=x_label, height=bar_height, width=2, alpha=0.4, color='red', label="实际平均成绩")  # 绘制每个学生实际平均成绩的bar,返回句柄
rects2 = plt.bar(x=[x + 2 for x in x_label], height=Total_mean_bar_height, width=2, alpha=0.4, color='blue', label="总的平均成绩{0}".format(np.round(Total_mean, 1)))

for rect in rects1: # 绘制bar上的文本
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width() / 2, height+1, str(height), ha="center", va="bottom")  # 在对应句柄下的bar上绘制文本str(height)

plt.xticks([index + 0.2 for index in x_label], [i for i in range(20)])  # 设置x轴值
plt.xlabel("学生序号")  # xlabel设置
plt.legend()   # 题注显示
plt.title("20个同学的平均成绩")  # 标题

结果展示:(图像似乎有点小,但是整体上不影响我们的练习)
在这里插入图片描述


任务四

5.任务四:计算及格率,以及绘制及格所占的饼状图

pass_rate = int(len(students_mean[students_mean>=60])/len(students_mean) * 100)  # 及格百分比
fail_rate = 100 - pass_rate  #  不及格百分比

plt.pie(x=(pass_rate, fail_rate), # 饼图中需要绘制的数据
        labels=('pass_rate', 'fail_rate'),  # 数据对应的标签
        explode=[0,1],   # 凸显部分——需要将第三个数据部分凸显,且整个绘图数据包含5个数据,那么就传入[0,0,1,0,0],对应位设置位非零
        colors=('pink', 'magenta'),  # 配置绘图可选颜色
        autopct='%.0f%%',  # 数据显示形式(不设置不显示数据,仅有图形划分)
        radius=2.8,  # 饼图半径
        labeldistance=1.2,  # 标签与圆心的距离
        wedgeprops={'linewidth':4,'edgecolor':'yellow'}, # 饼图边界设置:linewidth边界线宽度, edgecolor边界颜色
        textprops= {'fontsize':20,'color':'black'})  # 显示字体设置:fontsize大小, color颜色

结果展示:
在这里插入图片描述


练习总结

numpy基本讲解到这里就结束了,基本的语法规则,如np对象的概念,np数组的组成以及数据类型,还有np函数,广播规则等。
至于np中一些数学运算公式(如积分,平方等)和运算公式的应用将在另一个板块中展开。
接下来的板块将
从matplotlib和numpy的数学公式
运用展开。
大致模式如下:

  1. matplotlib绘图讲解。
  2. numpy在数学上的运算,实现数学公式的代码实现和基础语法的巩固。
  3. 完善补充板块练习内容。

往期回顾

用实践带领你进入numpy的世界——(一):numpy的效率和基本属性
用实践带领你进入numpy的世界——(二):numpy基本数组创建函数
用实践带领你进入numpy的世界——(三):numpy基本运算讲解
用实践带领你进入numpy的世界——(四):numpy基本函数运算(sum,mean……)
用实践带领你进入numpy的世界——(五):numpy广播运算讲解(加法为例)
numpy知道多少?感知篇——numpy的属性

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章