描述

利用附件中的成绩数据进行成绩统计,根据输入的同学的名字,输出其总分和平均分。根据输入的课程名字,输出这门课程的平均分、中位数和标准差。(输出结果中的数值保留2位小数)‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

输入格式

输入一个同学的名字‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬
输入一门课程的名字‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

输出格式

该同学在数组中的位置序号、平均成绩‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬
该门课程在数组中的位置序号、该课程平均成绩、中位数和标准差

题目要求用numpy实现,需要先导入numpy库,这是一个第三方库,需要用自行安装,安装方法是在命令提示符下输入:

  1. pip install numpy

导入numpy后一般为其设置别名为np:

  1. import numpy as np

读文件可以用Python方法:

  1. def readfile(filename):
  2. with open('成绩单数字.csv', 'r', encoding='utf-8') as file:
  3. score = file.read() # 读取文件中的数据到字符串中
  4. score = score.replace('\n', ',') # 替换字符串中的换行符为逗号,方便后面统一切分
  5. score = score.split(',') # 根据逗号将字符串切分为列表
  6. #score = file.read().replace('\n', ',').split(',') # 前面三行可以用这一行实现
  7. return score # 返回列表

也可以使用numpy中的loadtxt()读文件

  1. def readfile(filename):
  2. data = np.loadtxt(filename, str, delimiter=',', encoding='utf-8')
  3. return data

此时score为一个列表,内容如下:
[‘姓名’, ‘学号’, ‘高数’, ‘英语’, ‘python’, ‘物理’, ‘java’, ‘C语言’, ‘罗明’, ‘1217106’, ‘95’, ‘85’, ‘96’, ‘88’, ‘78’, ‘90’, ‘金川’, ‘1217116’, ‘85’, ‘86’, ‘90’, ‘70’, ‘88’, ‘85’, ‘戈扬’, ‘1217117’, ‘80’, ‘90’, ‘75’, ‘85’, ‘98’, ‘95’, ‘罗旋’, ‘1217119’, ‘78’, ‘92’, ‘85’, ‘72’, ‘95’, ‘75’, ‘蒋维’, ‘1217127’, ‘99’, ‘88’, ‘65’, ‘80’, ‘85’, ‘75’]

将这个列表转为numpy的数组,并按文件中数据的格式转为6行8列:

  1. def arrayshape(score): # score 为传入的列表
  2. scoreArray = np.array(score) # 列表转数组
  3. scoreArray = scoreArray.reshape(6, 8) # 一维数组转6行8列的二维数组
  4. # scoreArray = np.array(s).reshape(6, 8) # 前面两行可以用这一行实现
  5. return scoreArray # 返回数组,此时成绩的数据类型为字符串

scoreArray 是转为6行8列的数组,此时成绩的数据类型为字符串:
[[‘姓名’ ‘学号’ ‘高数’ ‘英语’ ‘python’ ‘物理’ ‘java’ ‘C语言’]
[‘罗明’ ‘1217106’ ‘95’ ‘85’ ‘96’ ‘88’ ‘78’ ‘90’]
[‘金川’ ‘1217116’ ‘85’ ‘86’ ‘90’ ‘70’ ‘88’ ‘85’]
[‘戈扬’ ‘1217117’ ‘80’ ‘90’ ‘75’ ‘85’ ‘98’ ‘95’]
[‘罗旋’ ‘1217119’ ‘78’ ‘92’ ‘85’ ‘72’ ‘95’ ‘75’]
[‘蒋维’ ‘1217127’ ‘99’ ‘88’ ‘65’ ‘80’ ‘85’ ‘75’]]

根据输入的学生姓名,返回学生位置序号,可以使用np.argwhere()函数:

  1. indexStudent = np.argwhere(scoreArray == studentName) # 返回学生所有位置,如[[4,0]]

计算学生平均成绩,需要根据学生所在位置序号中的行序号,对该行中的成绩数据进行统计,计算平均成绩。

  1. def studentInfo(studentName):
  2. scoreNum = scoreArray[1:, 2:].astype(int) # 数组scoreArray切片,将成绩部分转为整数
  3. indexStudent = np.argwhere(scoreArray == studentName) # 返回学生所有位置,如[[4,0]]
  4. studentRow = indexStudent[0,0] # 返回学生所在的行序号,如4
  5. meanStudent = np.mean(scoreNum[studentRow - 1]) # 计算学生平均成绩
  6. return indexStudent,round(meanStudent,2) # 返回位置序号和平均成绩

scoreNum 是仅包含成绩的整数数组,因有标题行存在,统计 时,行号要减1:
[[95 85 96 88 78 90]
[85 86 90 70 88 85]
[80 90 75 85 98 95]
[78 92 85 72 95 75]
[99 88 65 80 85 75]]
课程平均成绩的统计与前述方法类似,因为姓名和学号存在,列序号要减2:

  1. def courseInfo(courseName):
  2. scoreNum = scoreArray[1:, 2:].astype(int) # 数组scoreArray切片,将成绩部分转为整数
  3. indexcourse = np.argwhere(scoreArray == courseName) # 返回课程所有位置,如[[0,4]]
  4. courseColumn = indexcourse[0, 1] # 返回课程所在的列序号,如4
  5. meancourse = np.mean(scoreNum[0:, courseColumn - 2]) # 计算课程平均成绩
  6. mediancourse = np.median(scoreNum[0:, courseColumn - 2]) # 计算课程成绩中位数
  7. stdcourse = np.std(scoreNum[0:, courseColumn - 2]) # 计算成绩标准差
  8. return indexcourse,round(meancourse,2),round(mediancourse,2),round(stdcourse,2)

完整参考程序如下:

  1. #=============================================
  2. # 作者: 武汉理工大学 赵广辉
  3. # 日期: 2020.05.31
  4. #Email:30849528@qq.com
  5. # 版权: 作者原创,版权所有,谢绝转载
  6. # 教材:Python语言及其应用
  7. #=============================================
  8. import numpy as np
  9. def readfile(filename):
  10. with open(filename, 'r', encoding='utf-8') as file:
  11. score = file.read().replace('\n', ',').split(',') # 前面三行可以用这一行实现
  12. return score # 返回列表
  13. def arrayshape(score): # score 为传入的列表
  14. scoreArray = np.array(s).reshape(6, 8) # 前面两行可以用这一行实现
  15. return scoreArray # 返回仅包含成绩的整数数组
  16. def studentInfo(studentName):
  17. scoreNum = scoreArray[1:, 2:].astype(int) # 数组scoreArray切片,将成绩部分转为整数
  18. indexStudent = np.argwhere(scoreArray == studentName) # 返回学生所有位置,如[[4,0]]
  19. studentRow = indexStudent[0,0] # 返回学生所在的行序号,如4
  20. meanStudent = np.mean(scoreNum[studentRow - 1]) # 计算学生平均成绩
  21. return indexStudent,round(meanStudent,2)
  22. def courseInfo(courseName):
  23. scoreNum = scoreArray[1:, 2:].astype(int) # 数组scoreArray切片,将成绩部分转为整数
  24. indexcourse = np.argwhere(scoreArray == courseName) # 返回课程所有位置,如[[0,4]]
  25. courseColumn = indexcourse[0, 1] # 返回课程所在的列序号,如4
  26. meancourse = np.mean(scoreNum[0:, courseColumn - 2]) # 计算课程平均成绩
  27. mediancourse = np.median(scoreNum[0:, courseColumn - 2]) # 计算课程成绩中位数
  28. stdcourse = np.std(scoreNum[0:, courseColumn - 2]) # 计算成绩标准差
  29. return indexcourse,round(meancourse,2),round(mediancourse,2),round(stdcourse,2)
  30. if __name__ == '__main__':
  31. filename = '成绩单数字.csv' # 读取的文件名
  32. score = readfile(filename) # 调函数读文件,返回列表
  33. scoreArray = arrayshape(score) # 列表转数组
  34. studentName = input() # 输入学生姓名
  35. student = studentInfo(studentName) # 调用函数,返回学生序号和学生平均成绩
  36. print(f'{studentName}同学的位置序号为{student[0]}') # 输出学生位置序号
  37. print(f'{studentName}同学的平均成绩为{student[1]}') # 输出学生平均成绩
  38. courseName = input() # 输入课程名
  39. course = courseInfo(courseName) # 调用函数统计课程成绩,返回课程序号,平均分,中位数和标准差
  40. print(f'{courseName}课程位置序号{course[0]}') # 输出课程位置序号
  41. print(f'{courseName}平均成绩为{course[1]}分') # 输出课程平均成绩
  42. print(f'{courseName}成绩中位数为{course[2]}分') # 输出课程成绩中位数
  43. print(f'{courseName}成绩标准差为{course[3]}') # 输出课程成绩标准差

如果不考虑练习问题分解,分部代码写到一起也是可以的,下面给出部分功能的实现:

  1. with open('成绩单数字.csv', 'r', encoding='utf-8') as file:
  2. s = file.read().replace('\n', ',').split(',') # 读取文件中的数据到列表
  3. scoreAll = np.array(s).reshape(6, 8) # 将列表转数组再转为6行8列的二维数组
  4. print(scoreAll) # 输出数组scoreAll
  5. scoreNum = scoreAll[1:, 2:].astype(int) # 将数组中非数值型字符串部分去掉生成新数组
  6. print(scoreNum) # 输出数组
  7. print('python平均成绩为{}'.format(np.mean(scoreNum[:, 2]))) # 输出一门课的平均成绩
  8. print('python成绩中位数为{}'.format(np.median(scoreNum[:, 2]))) # 输出python成绩中位数
  9. print('python成绩标准差为{:.2f}'.format(np.std(scoreNum[:, 2]))) # 输出python成绩标准差
  10. print('{}同学的平均成绩为{:.2f}'.format(scoreAll[1, 0], np.mean(scoreNum[0, 0:])))