如何用Python和Pandas生成员工轮班序列及完整序列列?
解决方案
假设你的DataFrame包含Employee(员工姓名)、Cycle_type、Cycle_day、Shift列,先构造示例数据方便演示:
import pandas as pd data = { 'Employee': ['Alice']*8 + ['Bob']*6, 'Cycle_type': ['5-3']*8 + ['4-2']*6, 'Cycle_day': list(range(1,9)) + list(range(1,7)), 'Shift': ['M', 'M', 'A', 'A', 'N', 'Off', 'Off', 'Off', 'M', 'A', 'N', 'N', 'Off', 'Off'] } df = pd.DataFrame(data)
1. 生成到当前行的轮班序列(Sequence列)
要实现“到当前行的累计班次+次数”序列,分两步完成:
- 为每一行生成对应的
班次+累计次数项(比如第2次出现的M对应M2) - 按员工分组,逐行累计拼接这些项
代码实现:
# 生成每行的班次项:统计当前员工到当前行为止该班次的出现次数 df['shift_item'] = df.apply( lambda row: f"{row['Shift']}{df[(df['Employee'] == row['Employee']) & (df.index <= row.index) & (df['Shift'] == row['Shift'])].shape[0]}" if row['Shift'] != 'Off' else 'Off', axis=1 ) # 按员工分组,累计拼接所有历史班次项 df['Sequence'] = df.groupby('Employee')['shift_item'].transform( lambda group: group.expanding().apply(lambda x: ','.join(x), raw=True) )
说明:
- 第一个
apply遍历每行,通过筛选当前员工、当前行及之前的同班次记录,统计次数并拼接成M1/A2这类格式 expanding().apply逐行累计,把从第一行到当前行的所有shift_item用逗号连接,得到累计序列
2. 生成员工完整轮班序列(Full_sequence列)
先拼接每个员工的所有shift_item得到完整序列,再将其映射到该员工的每一行:
# 按员工分组,拼接所有班次项得到完整序列 full_seq_map = df.groupby('Employee')['shift_item'].apply(lambda x: ','.join(x)) # 将完整序列映射到原DataFrame的每一行 df['Full_sequence'] = df['Employee'].map(full_seq_map)
说明:
groupby.apply为每个员工生成所有班次项的逗号连接字符串- 用
map把完整序列赋值给该员工的每一行,确保同一员工的所有行都显示完整轮班序列
内容的提问来源于stack exchange,提问作者datadatadata
相关产品推荐
相关产品推荐

