现在有student.txt和score.txt数据文件,利用pandas求取每个班级的总分前三名的学生。然后将求取后的结果dataframe,利用seaborn完成数据可视化操作
首先导入pandas
import pandas as pd
然后利用pandas读取文件,将数据写入到dataframe里面
stuDF = pd.read_csv("./data/students.txt",names=['id','name','age','gender','clazz'])
scoreDF = pd.read_csv("./data/score.txt",names=['student_id','subject_id','score'])
查看一下数据
第一步:计算每个学生的总分
#第一步,计算每个学生的总分
# groupby为对原DataFrame进行打包分组,agg为聚合(其操作包括max、min、std、sum、count)
#(1)scoreDF.groupby('student_id')根据学生id进行聚合分组
#(2)scoreDF.groupby('student_id')['score'].agg('sum')根据分组计算每组的成绩socre总和
#(3)scoreDF.groupby('student_id')['score'].agg('sum').reset_index()通过reset_index重新设置连续的行索引index
#(4)最后rename(columns={'score':'sum_score'})将结果集中的score列名改为sum_socre
sumDF = scoreDF.groupby('student_id')['score'].agg('sum').reset_index().rename(columns={'score':'sum_score'})
sumDF.head()
第二步:将计算每个人成绩总和后的成绩表sumDF与学生表stuDF关联
#将计算每个人成绩总和后的成绩表sumDF与学生表stuDF关联
#(1)stuDF.merge(sumDF,left_on='id',right_on='student_id',how='left')将左表stuDF与右表sumDF关联
# 左表在括号外面,右表在括号里面,left_on是左表关联字段,right_on是右表关联字段
# how用来指定关联方式,有inner ,left,right几种选项
#(2)drop('student_id',axis=1)删除 student_id 这一列,axis是坐标轴,axis=0是行坐标轴,用来删除行,axis=1是列坐标轴,用来删除列
stu_sumDF = stuDF.merge(sumDF,left_on='id',right_on='student_id',how='left').drop('student_id',axis=1)
stu_sumDF.head()
第三步:增加几个新的列,给每行数据打上序号,然后利用序号来进行排序
# 增加几个新的列
# first与开窗函数的row_number一样,按照顺序打上序号排列
# min表示当两行数据的值相同时,两行数据的序号都为较小的序号。比如第3行和第4行的sum_score都为200,那么两行的first_rank的值都是3
# max表示当两行数据的值相同时,两行数据的序号都为较大的序号。比如第3行和第4行的sum_score都为200,那么两行的first_rank的值都是4
# dense与开窗函数的dense_rank一样,当两行数据的列值相同时,序号是 1,2,3,3,4
# average_rank类似于开窗函数的rank,序号会发生跳跃,但是列值相同时会求取平均值,
# 即当两行数据的列值相同时,序号是 1,2,3.5,3.5,5。其中,3.5是3和4的平均值
# ascending=False降序排列,ascending=True升序排序
stu_sumDF['first_rank'] = stu_sumDF.groupby('clazz')['sum_score'].rank(method='first',ascending=False)
stu_sumDF['min_rank'] = stu_sumDF.groupby('clazz')['sum_score'].rank(method='min',ascending=False)
stu_sumDF['max_rank'] = stu_sumDF.groupby('clazz')['sum_score'].rank(method='max',ascending=False)
stu_sumDF['dense_rank'] = stu_sumDF.groupby('clazz')['sum_score'].rank(method='dense',ascending=False)
stu_sumDF['average_rank'] = stu_sumDF.groupby('clazz')['sum_score'].rank(method='average',ascending=False)
第四步:按照sum_socre列值和之前增加的新的列进行排序
#先按照clazz排序,然后相同的clazz里面按照first_rank排序
# 在最后三行可以比较明显的看除不同排序字段的区别,当两行数据的列值相同时,应该如何打上序号
stu_sum_sortDF = stu_sumDF.sort_values(['clazz','first_rank'])
stu_sum_sortDF.head(17)
最后一步:利用布尔索引,找到每个班的总分前三名
#利用布尔索引,stu_sum_sortDF['first_rank']<=3返回的是一系列的true和false
clazz_top3 = stu_sum_sortDF[stu_sum_sortDF['first_rank']<=3]
clazz_top3.head()
数据分析部分到这里结束,现在得到了一个放着最终结果的dataframe,现在要利用seaborn来对其进行可视化处理
第一步:导包
#上面求处了每班总分前三名的dataframe,现在将这个dataframe可视化
import seaborn as sns
import matplotlib.pyplot as plt
第二步:解决中文乱码问题
# windows解决中文乱码
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
# mac解决中文乱码
# plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
第三步:利用直方图来完成可视化操作
#用直方图barplot来可视化
# x是x轴的列,y是y轴的列,hue是类别,也就是图上的蓝色,橙色,绿色,data是数据源dataframe
sns.barplot(x='clazz',y='sum_score',hue='first_rank',data=clazz_top3)
#上面的表不够美观,利用matplotlib.pyplot修改一下
#设置画布大小
plt.figure(figsize=(16,8))
#设置图的标题
plt.title("班级总分top3")
#绘图
sns.barplot(x='clazz',y='sum_score',hue='first_rank',data=clazz_top3)
#设置x轴和y轴的标签名
plt.xlabel("班级")
plt.ylabel("总成绩")
#设置y轴的刻度范围,从(0,650)变成(450,650),这样可以突出不同立方柱的高度差异
plt.ylim((450,650))
plt.show()