描述
利用附件中的成绩数据进行成绩统计,根据输入的同学的名字,输出其总分和平均分。根据输入的课程名字,输出这门课程的平均分、中位数和标准差。(输出结果中的数值保留2位小数)
输入格式
输入一个同学的名字
输入一门课程的名字
输出格式
该同学在数组中的位置序号、平均成绩
该门课程在数组中的位置序号、该课程平均成绩、中位数和标准差
题目要求用numpy实现,需要先导入numpy库,这是一个第三方库,需要用自行安装,安装方法是在命令提示符下输入:
pip install numpy
导入numpy后一般为其设置别名为np:
import numpy as np
读文件可以用Python方法:
def readfile(filename):
with open('成绩单数字.csv', 'r', encoding='utf-8') as file:
score = file.read() # 读取文件中的数据到字符串中
score = score.replace('\n', ',') # 替换字符串中的换行符为逗号,方便后面统一切分
score = score.split(',') # 根据逗号将字符串切分为列表
#score = file.read().replace('\n', ',').split(',') # 前面三行可以用这一行实现
return score # 返回列表
也可以使用numpy中的loadtxt()读文件
def readfile(filename):
data = np.loadtxt(filename, str, delimiter=',', encoding='utf-8')
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列:
def arrayshape(score): # score 为传入的列表
scoreArray = np.array(score) # 列表转数组
scoreArray = scoreArray.reshape(6, 8) # 一维数组转6行8列的二维数组
# scoreArray = np.array(s).reshape(6, 8) # 前面两行可以用这一行实现
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()函数:
indexStudent = np.argwhere(scoreArray == studentName) # 返回学生所有位置,如[[4,0]]
计算学生平均成绩,需要根据学生所在位置序号中的行序号,对该行中的成绩数据进行统计,计算平均成绩。
def studentInfo(studentName):
scoreNum = scoreArray[1:, 2:].astype(int) # 数组scoreArray切片,将成绩部分转为整数
indexStudent = np.argwhere(scoreArray == studentName) # 返回学生所有位置,如[[4,0]]
studentRow = indexStudent[0,0] # 返回学生所在的行序号,如4
meanStudent = np.mean(scoreNum[studentRow - 1]) # 计算学生平均成绩
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:
def courseInfo(courseName):
scoreNum = scoreArray[1:, 2:].astype(int) # 数组scoreArray切片,将成绩部分转为整数
indexcourse = np.argwhere(scoreArray == courseName) # 返回课程所有位置,如[[0,4]]
courseColumn = indexcourse[0, 1] # 返回课程所在的列序号,如4
meancourse = np.mean(scoreNum[0:, courseColumn - 2]) # 计算课程平均成绩
mediancourse = np.median(scoreNum[0:, courseColumn - 2]) # 计算课程成绩中位数
stdcourse = np.std(scoreNum[0:, courseColumn - 2]) # 计算成绩标准差
return indexcourse,round(meancourse,2),round(mediancourse,2),round(stdcourse,2)
完整参考程序如下:
#=============================================
# 作者: 武汉理工大学 赵广辉
# 日期: 2020.05.31
#Email:30849528@qq.com
# 版权: 作者原创,版权所有,谢绝转载
# 教材:Python语言及其应用
#=============================================
import numpy as np
def readfile(filename):
with open(filename, 'r', encoding='utf-8') as file:
score = file.read().replace('\n', ',').split(',') # 前面三行可以用这一行实现
return score # 返回列表
def arrayshape(score): # score 为传入的列表
scoreArray = np.array(s).reshape(6, 8) # 前面两行可以用这一行实现
return scoreArray # 返回仅包含成绩的整数数组
def studentInfo(studentName):
scoreNum = scoreArray[1:, 2:].astype(int) # 数组scoreArray切片,将成绩部分转为整数
indexStudent = np.argwhere(scoreArray == studentName) # 返回学生所有位置,如[[4,0]]
studentRow = indexStudent[0,0] # 返回学生所在的行序号,如4
meanStudent = np.mean(scoreNum[studentRow - 1]) # 计算学生平均成绩
return indexStudent,round(meanStudent,2)
def courseInfo(courseName):
scoreNum = scoreArray[1:, 2:].astype(int) # 数组scoreArray切片,将成绩部分转为整数
indexcourse = np.argwhere(scoreArray == courseName) # 返回课程所有位置,如[[0,4]]
courseColumn = indexcourse[0, 1] # 返回课程所在的列序号,如4
meancourse = np.mean(scoreNum[0:, courseColumn - 2]) # 计算课程平均成绩
mediancourse = np.median(scoreNum[0:, courseColumn - 2]) # 计算课程成绩中位数
stdcourse = np.std(scoreNum[0:, courseColumn - 2]) # 计算成绩标准差
return indexcourse,round(meancourse,2),round(mediancourse,2),round(stdcourse,2)
if __name__ == '__main__':
filename = '成绩单数字.csv' # 读取的文件名
score = readfile(filename) # 调函数读文件,返回列表
scoreArray = arrayshape(score) # 列表转数组
studentName = input() # 输入学生姓名
student = studentInfo(studentName) # 调用函数,返回学生序号和学生平均成绩
print(f'{studentName}同学的位置序号为{student[0]}') # 输出学生位置序号
print(f'{studentName}同学的平均成绩为{student[1]}') # 输出学生平均成绩
courseName = input() # 输入课程名
course = courseInfo(courseName) # 调用函数统计课程成绩,返回课程序号,平均分,中位数和标准差
print(f'{courseName}课程位置序号{course[0]}') # 输出课程位置序号
print(f'{courseName}平均成绩为{course[1]}分') # 输出课程平均成绩
print(f'{courseName}成绩中位数为{course[2]}分') # 输出课程成绩中位数
print(f'{courseName}成绩标准差为{course[3]}') # 输出课程成绩标准差
如果不考虑练习问题分解,分部代码写到一起也是可以的,下面给出部分功能的实现:
with open('成绩单数字.csv', 'r', encoding='utf-8') as file:
s = file.read().replace('\n', ',').split(',') # 读取文件中的数据到列表
scoreAll = np.array(s).reshape(6, 8) # 将列表转数组再转为6行8列的二维数组
print(scoreAll) # 输出数组scoreAll
scoreNum = scoreAll[1:, 2:].astype(int) # 将数组中非数值型字符串部分去掉生成新数组
print(scoreNum) # 输出数组
print('python平均成绩为{}'.format(np.mean(scoreNum[:, 2]))) # 输出一门课的平均成绩
print('python成绩中位数为{}'.format(np.median(scoreNum[:, 2]))) # 输出python成绩中位数
print('python成绩标准差为{:.2f}'.format(np.std(scoreNum[:, 2]))) # 输出python成绩标准差
print('{}同学的平均成绩为{:.2f}'.format(scoreAll[1, 0], np.mean(scoreNum[0, 0:])))