Python数据分析基础(余本国) 第四章练习
需求
- 班主任现有一班级的两张表,如下:
信息表:
成绩表:
现请帮班主任做如下工作:
1) 给成绩表加上姓名列;
2) 给成绩表加上字段“总分”列,并求出总分;
3) 增加列字段“等级”,标注每人“总分”的“优、良、中、及格、差”(270≤优,240≤良, 210≤中,及格≤180,差≤180);
4) 计算各门课程的平均成绩以及标准差;
5) 做"总分"成绩分布图,纵坐标表示成绩,横坐标表示学号或者姓名,画出总分的均分横线,让每位同学的总分圆点分布在均分线上下,以便于观察每位同学的成绩离开均分的距离。
引入pandas包进行数据分析和matplotlib.pyplot画图
import matplotlib.pyplot as plt
import pandas as pd
1) 给成绩表加上姓名列:
读取sheet数据
address = 'python实战.xlsx'
sheet1 = pd.read_excel(address, sheet_name='成绩表')
sheet2 = pd.read_excel(address, sheet_name='信息表', usecols=[0, 1]) # 读取0,1列
连接两个表
sheet = pd.merge(sheet1, sheet2, left_on='学号', right_on='学号') #按学号join
2) 给成绩表加上字段“总分”列,并求出总分:
没有将缺考成绩设为0的话,求和时将不会’线代‘列一起求和
sheet.loc[sheet['线代'] == '缺考', '线代'] = 0 # 将缺考的成绩设为0
temp = sheet[['C#', '线代', 'Python']] # 提取列
sheet['总分'] = temp.sum(axis=1) # 求和,axis=1为行,0位列
3) 增加列字段“等级”,标注每人“总分”的“优、良、中、及格、差”(270≤优,240≤良, 210≤中,及格≤180,差≤180):
bins = [0, 180, 210, 240, 270, 999] # 分区间
labels = ['差', '及格', '中', '良', '优']
sheet['等级'] = pd.cut(sheet.总分, bins, right=False, labels=labels) # right 右区间开
4) 计算各门课程的平均成绩以及标准差:
mean = sheet.mean() # 所有的平均数
std = sheet.std() # 所有的标准差
###### 输出各科的平均分和标准差数据
print(f'''{sheet}\n
C#的平均成绩为:{mean[1]},
C#的标准差为:{std[1]},
线代的平均成绩为:{mean[2]},
线代的标准差为:{std[2]},
Python的平均成绩为:{mean[3]},
Python的标准差为:{std[3]}.''')
输出结果:
5) 做"总分"成绩分布图,纵坐标表示成绩,横坐标表示学号或者姓名,画出总分的均分横线,让每位同学的总分圆点分布在均分线上下,以便于观察每位同学的成绩离开均分的距离:
做"总分"成绩分布图
plt.rcParams['font.sans-serif'] = ['Simhei'] # 设置可显示中文
total_mean = mean[4] # 总分平均分
plt.title('学生总分分布图')
plt.bar(range(len(sheet['总分'])), sheet['总分'], width=0.8)
plt.xticks(range(len(sheet['总分'])), sheet['姓名'])
plt.axhline(total_mean, color='red', linestyle='--')
plt.show()
附上完整代码
import matplotlib.pyplot as plt
import pandas as pd
address = 'python实战.xlsx'
sheet1 = pd.read_excel(address, sheet_name='成绩表')
sheet2 = pd.read_excel(address, sheet_name='信息表', usecols=[0, 1]) # 读取0,1列
sheet = pd.merge(sheet1, sheet2, left_on='学号', right_on='学号') # 连接两个表
sheet.loc[sheet['线代'] == '缺考', '线代'] = 0 # 将缺考的成绩设为0
temp = sheet[['C#', '线代', 'Python']] # 提取列
sheet['总分'] = temp.sum(axis=1) # 求和,axis=1为行,0位列
bins = [0, 180, 210, 240, 270, 999] # 分区间
labels = ['差', '及格', '中', '良', '优']
sheet['等级'] = pd.cut(sheet.总分, bins, right=False, labels=labels) # right 右区间开
mean = sheet.mean() # 所有的平均数
std = sheet.std() # 所有的标准差
# 输出各科的平均分和标准差数据
print(f'''{sheet}\n
C#的平均成绩为:{mean[1]},
C#的标准差为:{std[1]},
线代的平均成绩为:{mean[2]},
线代的标准差为:{std[2]},
Python的平均成绩为:{mean[3]},
Python的标准差为:{std[3]}.''')
# 做"总分"成绩分布图
plt.rcParams['font.sans-serif'] = ['Simhei'] # 设置可显示中文
total_mean = mean[4] # 总分平均分
plt.title('学生总分分布图')
plt.bar(range(len(sheet['总分'])), sheet['总分'], width=0.8)
plt.xticks(range(len(sheet['总分'])), sheet['姓名'])
plt.axhline(total_mean, color='red', linestyle='--')
plt.show()