QQ:3020889729 小蔡
特别声明
这是一个简单的学生成绩问题,以促进对numpy的认识、理解和运用。
本练习采用jupyter notebook运行,所以,如果是采用其它如pycharm的ide,需要将上一个任务需要的数据进行剪切才能正常运行。
jupyter notebook可以从上而下依次运行。
练习内容
- lambda关键字
- np.random.randint生成随机整数
- np.random.rand生成随机0~1的数
- np.round四舍五入保留小数位
- np.unique元素去重
- np.max取最大值
- narray.tolist(),np的narray对象转list数据对象
- np.mean取平均值
- np.flip反转数组
- np.sum求和
- plt.bar绘制条形图
- 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的数学公式运用展开。
大致模式如下:
- matplotlib绘图讲解。
- numpy在数学上的运算,实现数学公式的代码实现和基础语法的巩固。
- 完善补充板块练习内容。
往期回顾
用实践带领你进入numpy的世界——(一):numpy的效率和基本属性
用实践带领你进入numpy的世界——(二):numpy基本数组创建函数
用实践带领你进入numpy的世界——(三):numpy基本运算讲解
用实践带领你进入numpy的世界——(四):numpy基本函数运算(sum,mean……)
用实践带领你进入numpy的世界——(五):numpy广播运算讲解(加法为例)
numpy知道多少?感知篇——numpy的属性