Pandas数据处理|筛选与兼职打卡时间差异在一分钟内的全职打卡数据

举报
小小明-代码实体 发表于 2021/10/13 23:44:45 2021/10/13
【摘要】 需求与背景 某公司旗下有很多便利店,但近期却发现个别门店存在全职帮兼职打卡的情况,为此总部领导决定对所有门店的打卡时间数据进行分析,将每一个门店,全职人员和兼职人员上班卡、下班卡其中之一相差1分钟以内的...

需求与背景

某公司旗下有很多便利店,但近期却发现个别门店存在全职帮兼职打卡的情况,为此总部领导决定对所有门店的打卡时间数据进行分析,将每一个门店,全职人员和兼职人员上班卡、下班卡其中之一相差1分钟以内的数据找出来,然后再具体调查。

下面我们的任务就是以兼职人员数据为基准,找出相同门店下全职人员上班卡、下班卡其中之一相差1分钟以内的数据:

解决需求

首先读取数据(已脱敏):

import pandas as pd

excel = pd.ExcelFile("全职与兼职相差一分钟.xlsx")
df_fulltime = excel.parse("全职")
df_parttime = excel.parse("兼职")
display(df_fulltime.head())
print(df_fulltime.shape)
display(df_parttime.head())
print(df_parttime.shape)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

由于两张表的数据列名一致,我们可以将两张表拼接起来,方便分组:

df_fulltime["类型"] = "全职"
df_parttime["类型"] = "兼职"
df = pd.concat([df_fulltime, df_parttime], ignore_index=True)
df

  
 
  • 1
  • 2
  • 3
  • 4

测试分组和拆分:

for (area, store, time), df_split in df.groupby(["区域", "门店", "日期"]):
    print(area, store, time)
    df_fulltime_split = df_split.query("类型=='全职'")
    df_parttime_split = df_split.query("类型=='兼职'")
    display(df_fulltime_split)
    display(df_parttime_split)
    break

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

不过上述数据并没有能够匹配的数据,我们选个有结果的分组进行测试:

g = df.groupby(["区域", "门店", "日期"])
df_split = g.get_group(("DB区域", "54mh5", "2020-08-04"))
df_fulltime_split = df_split.query("类型=='全职'")
df_parttime_split = df_split.query("类型=='兼职'")
display(df_fulltime_split)
display(df_parttime_split)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

为了方便计算,获取上下班时间的分钟数:

def func(time_str):
    if not isinstance(time_str, str):
        return 0
    time_arr = time_str.split(":")
    return int(time_arr[0])*60+int(time_arr[1])


df_fulltime_time = df_fulltime_split[["上班卡", "下班卡"]].applymap(func)
df_parttime_time = df_parttime_split[["上班卡", "下班卡"]].applymap(func)

display(df_fulltime_time)
display(df_parttime_time)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

测试数据筛选:

for (time1, time2), row in zip(df_parttime_time.values, df_parttime_split.values[:, :-1]):
    print(time1, time2)
    print(row)
    idx = df_fulltime_time.query(
        f"{time1-1}<=上班卡<={time1+1} or {time2-1}<=下班卡<={time2+1}").index
    display(df_fulltime_split.loc[idx])
    break

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

测试数据整理:

result = []
data = df_fulltime_split.loc[idx].values[:, 3:-1]
row = row.tolist()
row.extend(data)
result.append(row)
result = pd.DataFrame(result)
result.rename(columns=dict(
    enumerate(["区域", "门店", "日期", "工号", "姓名", "上班卡", "下班卡"])), inplace=True)
result.rename(columns=lambda x: x if isinstance(
    x, str) else f"全职打卡{x-1}", inplace=True)
result

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

整理一下完整代码:

完整代码

import pandas as pd

excel = pd.ExcelFile("全职与兼职相差一分钟.xlsx")
df_fulltime = excel.parse("全职")
df_parttime = excel.parse("兼职")
df_fulltime["类型"] = "全职"
df_parttime["类型"] = "兼职"
df = pd.concat([df_fulltime, df_parttime], ignore_index=True)


def func(time_str):
    if not isinstance(time_str, str):
        return 0
    time_arr = time_str.split(":")
    return int(time_arr[0])*60+int(time_arr[1])


result = []
for (area, store, time), df_split in df.groupby(["区域", "门店", "日期"]):
    df_fulltime_split = df_split.query("类型=='全职'")
    df_parttime_split = df_split.query("类型=='兼职'")
    df_fulltime_time = df_fulltime_split[["上班卡", "下班卡"]].applymap(func)
    df_parttime_time = df_parttime_split[["上班卡", "下班卡"]].applymap(func)
    for (time1, time2), row in zip(df_parttime_time.values, df_parttime_split.values[:, :-1]):
        idx = df_fulltime_time.query(
            f"{time1-1}<=上班卡<={time1+1} or {time2-1}<=下班卡<={time2+1}").index
        if len(idx) > 0:
            data = df_fulltime_split.loc[idx].values[:, 3:-1]
            row = row.tolist()
            row.extend(data)
            result.append(row)
result = pd.DataFrame(result)
result.rename(columns=dict(
    enumerate(["区域", "门店", "日期", "工号", "姓名", "上班卡", "下班卡"])), inplace=True)
result.rename(columns=lambda x: x if isinstance(
    x, str) else f"全职打卡{x-1}", inplace=True)
result

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

最终结果:

文章来源: xxmdmst.blog.csdn.net,作者:小小明-代码实体,版权归原作者所有,如需转载,请联系作者。

原文链接:xxmdmst.blog.csdn.net/article/details/117707218

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。