按时间规则调整DataFrame行:规整员工打卡时间至对应列
员工打卡时间规整实现方案
现有代码与初始输出
现有用于生成打卡日志的Pandas代码:
dic = {'Employee ID':emp_id, 'Log Date':emp_logdate, 'Log Time':emp_logtime} df = pd.DataFrame(dic).groupby(['Employee ID','Log Date']).agg({'Log Date':'first', 'Log Time': lambda x: ', '.join(x.unique())})['Log Time'].astype(str).str.split(', ', expand=True).reset_index()
运行后得到的初始DataFrame(仅展示时间列):
'7:20', '11:50', '12:49', '17:20' '7:02', '11:36', '12:59' '11:33', '12:40', '17:06' '11:38'
需求说明
需要将零散的打卡时间按规则归类到指定列:
- 7点左右的时间 → AM In列
- 11点左右的时间 → AM Out列
- 12点左右的时间 → PM In列
- 17点左右的时间 → PM Out列
缺失时段的位置填充空值,最终得到规整的结构化数据。
实现方案
步骤1:定义时间分类逻辑
先通过提取时间的小时部分,为每个目标列设置匹配范围:
import pandas as pd def classify_time(time_str): if pd.isna(time_str): return None # 转换为时间格式并提取小时 hour = pd.to_datetime(time_str, format='%H:%M').hour if 6 <= hour <= 8: # 匹配7点左右的打卡 return 'AM In' elif 10 <= hour <= 12: # 匹配11点左右的打卡 return 'AM Out' elif 12 <= hour <= 13: # 匹配12点左右的打卡 return 'PM In' elif 16 <= hour <= 18: # 匹配17点左右的打卡 return 'PM Out' else: return None
步骤2:逐行处理重组数据(适合小数据量)
保留原数据的Employee ID和Log Date列,遍历每行时间值并按规则填充到目标列:
# 获取所有时间列(排除前两列的ID和日期) time_cols = df.columns[2:] # 初始化结果DataFrame,添加目标列并设为空值 target_cols = ['AM In', 'AM Out', 'PM In', 'PM Out'] result_df = df[['Employee ID', 'Log Date']].copy() for col in target_cols: result_df[col] = '' # 遍历每行处理时间分类 for idx, row in df.iterrows(): for col in time_cols: time_val = row[col] if pd.notna(time_val): col_type = classify_time(time_val) # 仅填充空的目标列(避免同一时段多个打卡覆盖) if col_type and result_df.at[idx, col_type] == '': result_df.at[idx, col_type] = time_val
替代方案:向量化处理(适合大数据量)
用melt和pivot实现批量转换,效率更高:
# 将宽格式时间列转为长格式,过滤空值 melted = df.melt(id_vars=['Employee ID', 'Log Date'], value_name='Log Time').dropna(subset=['Log Time']) # 为每个时间标记所属列类型 melted['Col_Type'] = melted['Log Time'].apply(classify_time) # 去重:同一员工同一日期同一时段仅保留第一个打卡 melted = melted.drop_duplicates(subset=['Employee ID', 'Log Date', 'Col_Type']) # 转回宽格式,补全目标列并填充空值 result_df = melted.pivot(index=['Employee ID', 'Log Date'], columns='Col_Type', values='Log Time').reset_index() result_df = result_df.reindex(columns=['Employee ID', 'Log Date'] + target_cols).fillna('')
最终效果
运行后得到的规整数据示例:
Employee ID Log Date AM In AM Out PM In PM Out 0 2024-05-01 7:20 11:50 12:49 17:20 1 2024-05-01 7:02 11:36 12:59 2 2024-05-02 11:33 12:40 17:06 3 2024-05-02 11:38
内容的提问来源于stack exchange,提问作者nj castillo
相关产品推荐
相关产品推荐

