Pandas聚合员工休假数据时日期格式异常及多类型统计方案
解决Pandas分组统计员工休假天数及日期的问题
问题根源
- 原代码中
str(group["date"])会将整个dateSeries转为带元数据的字符串(例如0 2024-01-01\n1 2024-01-02\nName: date, dtype: datetime64[ns]),导致holiday_date出现重复内容和格式异常。 - 使用
group["date"].values时,datetime64类型与空字符串str()无法兼容,触发类型不匹配错误。
解决方案:自定义聚合函数实现精准统计
直接针对每种休假状态筛选对应日期并格式化,避免类型冲突,同时生成清晰的统计结果:
1. 确保日期列格式正确
import pandas as pd # 若date列未转为datetime类型,先执行转换 df['date'] = pd.to_datetime(df['date'])
2. 定义聚合函数处理三种休假类型
def agg_leave_details(group): # 提取并格式化假期(H)的日期 holiday_dates = group[group['status'] == 'H']['date'].dt.strftime('%Y-%m-%d').tolist() # 提取并格式化事假(*AL)的日期 leave_dates = group[group['status'] == '*AL']['date'].dt.strftime('%Y-%m-%d').tolist() # 提取并格式化病假(*SL)的日期 sick_dates = group[group['status'] == '*SL']['date'].dt.strftime('%Y-%m-%d').tolist() return pd.Series({ 'holiday_count': len(holiday_dates), 'holiday_dates': ', '.join(holiday_dates) if holiday_dates else '', 'leave_count': len(leave_dates), 'leave_dates': ', '.join(leave_dates) if leave_dates else '', 'sick_leave_count': len(sick_dates), 'sick_leave_dates': ', '.join(sick_dates) if sick_dates else '' })
3. 分组统计并重置索引
result_df = df.groupby(['emp_code', 'emp_name']).apply(agg_leave_details).reset_index()
4. 导出结果到Excel
result_df.to_excel('员工休假统计.xlsx', index=False)
备选方案:使用PivotTable模块化处理
如果需要更模块化的实现,可以拆分计数和日期拼接逻辑:
# 先格式化日期为字符串 df['formatted_date'] = df['date'].dt.strftime('%Y-%m-%d') # 统计各类型休假天数 count_table = df.pivot_table( index=['emp_code', 'emp_name'], columns='status', values='date', aggfunc='count', fill_value=0 ).rename(columns={ 'H': 'holiday_count', '*AL': 'leave_count', '*SL': 'sick_leave_count' }) # 拼接各类型休假日期 date_table = df.pivot_table( index=['emp_code', 'emp_name'], columns='status', values='formatted_date', aggfunc=lambda x: ', '.join(x) if x.size > 0 else '', fill_value='' ).rename(columns={ 'H': 'holiday_dates', '*AL': 'leave_dates', '*SL': 'sick_leave_dates' }) # 合并结果 result_df = pd.concat([count_table, date_table], axis=1).reset_index()
内容的提问来源于stack exchange,提问作者Redgrave
相关产品推荐
相关产品推荐

