记录一次使用python编写程序用于统计公司员工工时情况

        来到公司后我接手了公司每月一次的部门工时统计的活,这个活不难但是很费时间,于是产生了编写一个脚本程序来为我自动统计工时的想法,可以大大节约人力成本和时间。

        选择python的原因是因为python是一门非常流行的解释性语言,具有很高的可读性和可维护性,易于上手理解,广泛应用于数据科学和机器学习领域。python具有非常丰富的第三方库,我主要使用了pandas库来解决这个需求,这些库可以帮助我们更方便地进行数据处理和分析。

        1.首先安装pandas库,可以使用"pip install pandas"在终端安装pandas库;

        2.由于原始表格中的数据是非常多的,并且有部分数据是有缺失的,所以需要先对这些数据进行整理,删掉用不到的数据,然后把缺失的数据进行填充。这里我使用了将整理后的数据生成一张新的excel表格的方式。由于原始表格中缺失数据的那一行总是对前一行的补充,因此将前一条的数据填入进去;

# 读取原始表格数据
df = pd.read_excel('path/to/your/file.xlsx')

# 指定统计日期范围('%Y/%m/%d')
first_day = pd.to_datetime('2023/3/1')
last_day = pd.to_datetime('2023/3/31')

# 取出所需的三列数据,并复制一份新的数据框
new_df = df[['单据状态', '录单人', '录单日期', '工时(小时)', '主项目名称']].copy()

# 将列名修改为姓名、日期、工作时长
new_df.columns = ['审核状态', '姓名', '日期', '工作时长', '主项目名称']

# 对列中的缺失值进行填充,填充方式是将前一条数据填入进去
new_df['审核状态'].fillna(method='ffill', limit=len(new_df)-1, inplace=True)
new_df['姓名'].fillna(method='ffill', limit=len(new_df)-1, inplace=True)
new_df['日期'].fillna(method='ffill', limit=len(new_df)-1, inplace=True)
new_df['主项目名称'].fillna(method='ffill', limit=len(new_df)-1, inplace=True)

# 去掉新表格中的最后一行
new_df.drop(new_df.tail(1).index, inplace=True)

# 删除审核状态为“重新审核”的那行数据
new_df = new_df[new_df['审核状态'] != '重新审核']

# 将新表格保存为xlsx文件
new_df.to_excel('data.xlsx', index=False)

        3.接下来读取新生成的表格,使用新生成的表格进行数据统计。我需要程序能统计出某位员工在某个工作日的工作时长是否等于8小时,如果不等于8则需要输出具体哪个工作日个多少小时。还需要程序能统计出哪位员工缺少哪个工作日的数据,缺少的那一天需要能输出出来。还有总工作天数、总工作时长、平均工作时长这些数据。

        具体来讲以下代码使用了pandas库中的groupby()函数对数据进行聚合操作以计算每个员工每个工作日的工作时长;使用了date_range()函数生成日期序列,使用了循环和条件语句处理数据中的问题和缺失值,并计算总工作天数、总工作时长和平均工作时长等统计量;最后使用了pandas dataframe将统计结果存储为表格,并通过to_excel()和to_csv()函数输出到文件中。

        代码中每一步过程都有注释,保证代码的易读性。

# 读取Excel数据,并指定日期列格式为"%Y/%m/%d"
df = pd.read_excel('data.xlsx', parse_dates=['日期'], date_format='%Y/%m/%d')

# 对数据进行排序,以便后续计算每个员工每个工作日的工作时长
df.sort_values(by=['姓名', '日期'], inplace=True)

# 计算每个员工每个工作日的工作时长
df['工作时长'] = df.groupby(['姓名', '日期'])['工作时长'].transform('sum')

# 获取所有员工的名称
employees = set(df['姓名'])

# 存储分析结果的列表
result = []

# 遍历每个员工,统计总工作天数、总工作时长和平均工作时长
for name in employees:

    # 获取该员工在该月份内的所有数据
    data = df[df['姓名'] == name]

    # 统计总工作天数和总工作时长,并计算平均工作时长
    days, hours, problems, missing_days = [], [], [], []
    all_days = pd.date_range(first_day, last_day, freq='D')
    for day in all_days:
        work_hours = data[data['日期'] == day]['工作时长'].values
        if len(work_hours) > 0 and not pd.isna(work_hours[0]):
            if work_hours[0] == 8:
                days.append(day)
                hours.append(work_hours[0])
            else:
                problems.append((day, work_hours[0]))
                days.append(day)
                hours.append(work_hours[0])
        else:
            day_of_week = day.weekday()
            if day_of_week != 5 and day_of_week != 6 and day not in holidays:
                missing_days.append(day)

    # 处理结果并添加到结果列表中
    total_days = len(days)
    total_hours = sum(hours)
    avg_hours = round(total_hours / total_days, 2)

    problem_desc = '问题数据:{}'.format(' ;'.join(
        [d[0].strftime('%Y/%m/%d') + (f":工时:{str(d[1])}小时 " if not pd.isna(d[1]) else "") for d in problems]))
    missing_days_desc = '缺少数据:{}'.format(' ;'.join([d.strftime('%Y/%m/%d') for d in missing_days]))
    problem_data = '; '.join(
        [d[0].strftime('%Y/%m/%d') + (f":{str(d[1])}" if not pd.isna(d[1]) else "") for d in problems])
    missing_data = '; '.join([d.strftime('%Y/%m/%d') for d in missing_days])
    result.append((name, total_days, total_hours, avg_hours, problem_data, missing_data))

# 将分析结果转换为Pandas DataFrame
result_df = pd.DataFrame(result, columns=['姓名', '总工作天数', '总工作时长', '平均工作时长', '问题数据', '缺失数据'])

# 输出结果到Excel表格中
# result_df.to_excel('path/to/your/file.xlsx', index=False)
result_df.to_excel('工作时长分析结果.xlsx', index=False)

# 将工作时长分析结果.xlsx转为csv文件
new_df_from_excel = pd.read_excel('path/工作时长分析结果.xlsx')
new_df_from_excel.to_csv('path/工作时长分析结果.csv', index=False)

        4. 由于csv格式比xlsx格式更加通用因此最后我做了一个格式转换,最终程序会生成三个文件,一个是保存了整理后的数据的表格,还有两个是最终的工作时长分析结果,程序输出结果符合我的需求。

        最后附一张好看的壁纸。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值