案例:利用Pandas按年月、考试科目汇总学生成绩并展示为并列柱状图

需求

现有一批学生成绩,需要分析不同月份各科考试成绩波动情况,根据数据可知,即按照考试月份及考试科目对成绩汇总求平均成绩。
在这里插入图片描述

在这里插入图片描述

问题解决

根据数据源结构可知,主要难点如下:

  1. 源数据中的日期列格式为年/月/日,为便于汇总,需转换为年/月格式。
  2. 需要按日期考试科目分数进行分组并求均值。
  3. 需要将分析结果以柱状图的形式进行展示

关键中间结果

读取数据

data = pd.read_excel("考试分数.xlsx")
df = data[['日期','考试科目','分数']]

在这里插入图片描述

转换日期

df["日期"]=pd.to_datetime(df["日期"],format='%Y/%m/%d',errors='coerce').dt.to_period('m')

在这里插入图片描述

分组汇总

data=df.groupby([df['日期'],df['考试科目']]).agg('mean')

在这里插入图片描述

转换分组结果

data=df.groupby([df['日期'],df['考试科目']]).agg('mean').unstack()

在这里插入图片描述

data.index

输出:

PeriodIndex(['2013-11', '2013-12', '2014-01', '2014-02', '2014-03', '2014-04',
             '2014-05'],
            dtype='period[M]', name='日期2', freq='M')
data.columns

输出:

MultiIndex([('分数', '数学'),
            ('分数', '科学'),
            ('分数', '阅读')],
           names=[None, '考试科目'])

完整代码

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# 设置字体
plt.rcParams['font.family'] = 'simhei'

# 读取数据
data = pd.read_excel("考试分数.xlsx")
df = data[['日期','考试科目','分数']]
# 将日期转换为年-月格式
df["日期"]=pd.to_datetime(df["日期"],format='%Y/%m/%d',errors='coerce').dt.to_period('m')
# 先按年月、考试科目分组数据,再求平均分数
data=df.groupby([df['日期'],df['考试科目']]).agg('mean').unstack().round(2)
# 使用pandas绘制并列柱状图
data.plot(kind='bar')

# 使用matplotlib绘制并列柱状图
# x = np.arange(len(data.index)) 
# labels = data.index
# plt.xticks(x, labels)
# width = 0.25 
# b1=plt.bar(x - width, data['分数','数学'], width, label='1')
# plt.bar_label(b1, label_type='edge',fontsize=8)
# b2=plt.bar(x, data['分数','科学'], width, label='2')
# plt.bar_label(b2, label_type='edge')
# b3=plt.bar(x + width, data['分数','阅读'], width, label='3')
# plt.bar_label(b3, label_type='edge')

plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值