You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为pandas透视表添加计算列,实现Django学生考勤报表出勤占比统计

实现方案

你可以直接在现有pandas处理逻辑的基础上新增行维度的统计计算,不需要改现有查询逻辑,修改后的视图层代码如下:

import pandas as pd
import calendar
from .models import StudentAttendance

# 请根据你数据库Status字段实际存储的取值修改映射关系
STATUS_MAPPING = {
    "attend": "出勤",
    "absent": "缺勤",
    "leave": "请假"
}
# 可动态传入年、月参数替换固定值
year = 2024
month = 9
# 取当月自然月总天数,若只需按实际考勤天数计算,后续替换为 len(df['Date'].unique())
total_days = calendar.monthrange(year, month)[1]

attend = StudentAttendance.objects.filter(ClassKey_id=2, Date__month=month, Date__year=year).values('EnrollID_id','EnrollID__AcademicRollNo','EnrollID__AdminKey__SNameE', 'Date', 'Status' ).order_by('Date', 'id')

df = pd.DataFrame(attend)
# 新增状态标记列用于后续统计
df['is_attend'] = df['Status'] == STATUS_MAPPING['attend']
df['is_absent'] = df['Status'] == STATUS_MAPPING['absent']
df['is_leave'] = df['Status'] == STATUS_MAPPING['leave']

# 生成原有日度考勤透视表
table = df.pivot_table(
    index=['EnrollID__AcademicRollNo', 'EnrollID__AdminKey__SNameE'], 
    columns=[pd.to_datetime(df.Date).dt.day], 
    values=['Status'], 
    aggfunc=','.join
)
# 可选:填充无考勤记录的空缺值
table = table.fillna('未打卡')

# 按学生维度统计三个率
stat = df.groupby(['EnrollID__AcademicRollNo', 'EnrollID__AdminKey__SNameE']).agg(
    出勤数=('is_attend', 'sum'),
    缺勤数=('is_absent', 'sum'),
    请假数=('is_leave', 'sum')
).reset_index().set_index(['EnrollID__AcademicRollNo', 'EnrollID__AdminKey__SNameE'])

stat['出勤率'] = stat['出勤数'].apply(lambda x: f"{round(x/total_days*100,1)}%")
stat['缺勤率'] = stat['缺勤数'].apply(lambda x: f"{round(x/total_days*100,1)}%")
stat['请假率'] = stat['请假数'].apply(lambda x: f"{round(x/total_days*100,1)}%")

# 合并统计列到原有透视表右侧
final_table = table.join(stat[['出勤率','缺勤率','请假率']])

context={ 'table':final_table.to_html(table_id='dataframe') }
return render(request, 'student/attendance_report.html', context)

注意事项

  • 上述代码无需修改前端渲染逻辑,原有{{table|safe}}可直接兼容
  • 可根据业务需要调整百分比的小数位数、空缺值显示内容
  • 如果需要给统计列加特殊样式,可在to_html之后通过JS/CSS匹配表格最后三列做自定义渲染

大流量场景优化方案

如果单月考勤数据量超过10万条,可将统计逻辑下沉到Django ORM层做预聚合,减少pandas内存占用:

  • 单独用ORM分组查询每个学生的出勤/缺勤/请假计数
  • 将计数结果和透视表数据合并后再渲染,整体逻辑和上述方案一致

内容的提问来源于stack exchange,提问作者Inouguys

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:06:07