提取一行数据列表_【数据分析入门】Python解题思路分解——成绩单统计分析

今天这篇入门向主要针对自己在教程中遇到的一个具体的数据分析问题分享一下解题思路和踩过的坑。

3de416142b51e0279b1cc247cae5dad6.gif3de416142b51e0279b1cc247cae5dad6.gif61751f14f83a1a5511414ddabcfa8afb.gif

问题

从成绩单文件提取数据并进行如下统计分析:

  1. 读取 report.txt 文件中的成绩;

  2. 统计每名学生总成绩、计算平均并从高到低重新排名;

  3. 汇总每一科目的平均分和总平均分(见下表第一行);

  4. 添加名次,替换60分以下的成绩为“不及格”;

  5. 将处理后的成绩另存为一个新文件(result.txt)。

文件我放到这里,如果你有兴趣欢迎你下载尝试:

姓名 语文 数学 英语 物理 化学 生物 政治 历史 地理小赵 73 85 80 82 93 41 64 87 55小钱 33 91 81 92 72 50 50 65 83小孙 95 64 87 79 34 70 45 72 87小李 87 34 81 58 73 41 46 74 97小周 54 58 66 65 42 43 70 33 89小吴 55 83 80 94 90 86 44 33 64小郑 84 93 59 94 86 71 69 81 71小王 75 83 31 53 72 34 33 64 80小冯 36 74 83 69 57 78 73 59 58小陈 98 90 64 71 90 65 40 33 89小楮 90 47 70 34 88 73 69 74 60小卫 70 67 33 96 94 69 62 72 72小蒋 82 43 63 70 60 67 54 69 92小沈 94 95 72 86 78 78 43 95 96小韩 83 70 36 74 50 56 38 93 78小杨 86 93 87 46 75 44 45 60 81小朱 97 91 88 86 86 54 61 56 82小秦 47 51 64 78 89 91 37 94 61小尤 74 67 63 53 34 89 56 66 76小许 50 72 99 31 38 92 62 92 65小何 86 40 86 57 76 92 79 95 52小吕 51 33 81 48 95 80 51 81 99小施 88 74 38 48 78 87 96 88 90小张 43 87 44 88 95 78 91 42 94小孔 37 86 88 83 80 90 31 78 37小曹 63 53 55 94 45 55 73 91 78小严 36 71 77 60 91 79 90 37 61小华 53 85 85 72 62 87 94 73 34小金 78 84 77 42 79 82 50 74 94小魏 75 57 38 85 58 60 97 99 69

要求的输出结果:

名次 姓名 语文 数学 英语 物理 化学 生物 政治 历史 地理 总分 平均分0 平均 72 67 76 47 63 73 77 73 82 630 70.01 小S 94 90 96 89 92 84 83 80 82 790 87.82 小D 90 88 87 89 82 79 79 83 85 762 84.73 小A 89 94 90 96 89 92 不及格 73 80 757 84.1...21 小K 82 不及格 83 63 66 67 72 83 86 638 70.9...

3de416142b51e0279b1cc247cae5dad6.gif3de416142b51e0279b1cc247cae5dad6.gif61751f14f83a1a5511414ddabcfa8afb.gif

初步判断

第一步我理解需要先来判断这道题用到了哪些知识点,比如:txt文件读取,列表切片,算术计算,列表排序,文件写入。

确认好应用到哪些知识以后,扫一下有没有知识盲区,我个人重新去翻了一遍列表切片和排序操作。下面我们开始解题。

3de416142b51e0279b1cc247cae5dad6.gif3de416142b51e0279b1cc247cae5dad6.gif61751f14f83a1a5511414ddabcfa8afb.gif

读取成绩

这里涉及到txt文件读取,比较容易:

#读取成绩with open('report.txt','r') as f:    student_report = f.readlines()

这里的问题是每一行的学生成绩是一个字符串类型,导致无法对每一科分数进行统计,所以我们需要创建新的列表,列表中的元素为每行字符串转换后的新列表。

#建立空列表,把每一行字符串类型转为列表对象records = []for report in student_report:    string = report.split()    records.append(string)

到这里我们完成了成绩读取及数据准备的相关工作。

3de416142b51e0279b1cc247cae5dad6.gif3de416142b51e0279b1cc247cae5dad6.gif61751f14f83a1a5511414ddabcfa8afb.gif

修改表头

对比输出结果样例,我们发现表头部分有跟输入有变化,增加了名次,平均分和总分三列,所以我们拿出records列表的第一个元素records[0]进行扩展,用到insert和extend方法

#表头增加名次、总分、平均分records[0].insert(0,'名次')records[0].extend(['总分','平均分'])

3de416142b51e0279b1cc247cae5dad6.gif3de416142b51e0279b1cc247cae5dad6.gif61751f14f83a1a5511414ddabcfa8afb.gif

计算每个学生的总分和平均分

这部分思路比较清晰,遍历每一行数据,将各科成绩做累加得到总分,总分除以科目数得到平均分。

#计算总分与平均分for record in records[1:]:    #初始化总分和平均分    sum_record = 0    avg_record= 0    #计算总分时要略过名字    for data in record[1:]:        sum_record += int(data) #每行总分    avg_record = round(sum_record/len(record[1:]),2) #每行平均分,保留两位小数    record.extend([str(sum_record),str(avg_record)]) #将总分和平均分插入到每行的后面

3de416142b51e0279b1cc247cae5dad6.gif3de416142b51e0279b1cc247cae5dad6.gif61751f14f83a1a5511414ddabcfa8afb.gif

计算每一科的平均分

这部分是我刚开始一直没搞定的地方,主要没想清楚如何计算每列的总和。其实分以下几步,首先弄清楚一共有多少科的数据也就是列数,对于每一列我们要求一个总和,外层循环也就很容易确定。然后需要取到每列的各行数据,这里需要按列数的索引来进行每一行数据的相加。最后是求平均分,并将所有数据存入各科平均分的列表中。

#计算各列平均分avg_scores = ['平均分'] #列表存放每科平均分nums = len(results[1]) #计算要遍历多少列for num in range(1,nums):    sum_score = 0    avg_score = 0    if num < nums-1:        for i in results[1:]:            sum_score += int(i[num]) #求每一列总分        sum_avg = int(sum_score/len(results[1:])) # 求除最后一列外的平均分,因为题目中最后一列是一位小数,其余列是整数        avg_scores.append(sum_avg)    else:        for i in results[1:]:            sum_score += float(i[num])        sum_avg = round((sum_score/len(results[1:])),1) #最后一列保留一位小数        avg_scores.append(sum_avg)        results.insert(1,avg_scores) #插入平均分

由于给出的样例中,总平均分是保留一位小数,而各科平均分均为整数,这里加入了if判断。

3de416142b51e0279b1cc247cae5dad6.gif3de416142b51e0279b1cc247cae5dad6.gif61751f14f83a1a5511414ddabcfa8afb.gif

插入名次替换不及格成绩

由于前面已经对列表进行了排序,所以这里直接插入名次列即可。替换60分以下成绩为不及格,刚开始忘记了如何直接替换列表元素。需要找到成绩对应对索引值,接着用列表名+索引值的方式进行替换。

#插入名次order = 0for result in results[1:]:    result.insert(0,order)    order += 1    #替换60分以下成绩为不及格    for i in result[2:-2]:        if int(i) < 60:            result[result.index(i)] = '不及格'

3de416142b51e0279b1cc247cae5dad6.gif3de416142b51e0279b1cc247cae5dad6.gif61751f14f83a1a5511414ddabcfa8afb.gif

写入结果文件

终于来到了胜利前的最后一步,将结果写入一个新的文本文件中。这里需注意的是,要把成绩全部转换为字符串后再写入,方便调整格式。

#写入文本with open('report_final.txt','w',encoding='UTF-8') as f:    for result in results:        result = [str(i) for i in result] #全部转换为字符串        f.write(' '.join(result))        f.write('\n')

总结:非常艰辛的一次做题体验,这里没有用到数据分析专用的pandas包,因为我还没有学,后面学习之后回头优化应该会有新的收获。加油吧。

d90f2e90c6365d28ea6d27ed15ec778e.png fd6f45a73f4925facc86d62f140a0ca1.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值