我有一个Pandas格式的数据框,它反映了员工的轮班情况(他们实际工作的时间),下面是它的一个片段:
df = pd.DataFrame({'Worker' : ['Alice','Alice','Alice', 'Bob','Bob','Bob'],
'Shift_start' : ['2022-01-01 10:00:00', '2022-01-01 13:10:00', '2022-01-01 15:45:00', '2022-01-01 11:30:00', '2022-01-01 13:40:00', '2022-01-01 15:20:00'],
'Shift_end' : ['2022-01-01 12:30:00', '2022-01-01 15:30:00', '2022-01-01 17:30:00', '2022-01-01 13:30:00', '2022-01-01 15:10:00', '2022-01-01 18:10:00']})
| 工人|移位_开始|班次_结束|
| - ------| - ------| - ------|
| 爱丽丝|2022年1月1日10时00分|2022年1月1日12时30分|
| 爱丽丝|2022年1月1日13时10分|2022年1月1日15时30分|
| 爱丽丝|2022年1月1日15时45分|2022年1月1日17时30分|
| 鲍勃|2022年1月1日11时30分|2022年1月1日13时30分|
| 鲍勃|2022年1月1日13时40分|2022年1月1日15时10分|
| 鲍勃|2022年1月1日15时20分|2022年1月1日18时10分|
现在,我需要在每一行中计算自上次部分中断以来的时间,定义为暂停〉20分钟,并根据每个班次的开始时间计算。即,如果暂停15分钟,则应认为暂停不存在,并计算自上次〉20分钟暂停以来的时间。如果不存在暂停,这个时间应该是从一天开始算起的时间。所以我需要这样的东西:
| 工人|移位_开始|班次_结束|休息后小时数|
| - ------| - ------| - ------| - ------|
| 爱丽丝|2022年1月1日10时00分|2022年1月1日12时30分|无|
| 爱丽丝|2022年1月1日13时10分|2022年1月1日15时30分|无|
| 爱丽丝|2022年1月1日15时45分|2022年1月1日17时30分|二点五八|
| 鲍勃|2022年1月1日11时30分|2022年1月1日13时30分|无|
| 鲍勃|2022年1月1日13时40分|2022年1月1日15时10分|二、十七|
| 鲍勃|2022年1月1日15时20分|2022年1月1日18时10分|三点八三|
对于Alice,第一行为0,因为没有先前的休息时间,所以将其作为自一天开始以来的值。由于这是她的第一个班次,因此结果为0小时。在第二行中,她刚刚暂停了40分钟,因此自休息以来再次为0小时。在第三行中,她刚刚休息了15分钟,但由于最小休息时间为20分钟,就好像她没有休息过一样,因此,自从她最后一次休息以来的时间是从她最后一次休息结束的13:10:00开始的,所以结果是2小时35分钟,即2.58小时。
在Bob的情况下,同样的逻辑也适用。第一行是0(是一天的第一班)。在第二排,他只休息了10分钟,这不算,所以从最后一次休息开始的时间应该是从他一天开始的时间,即2h10m在第三排,他又休息了10分钟,所以时间又是从一天开始的,所以3h50m(3.83小时)。
为了计算20分钟限制的休息时间,我做了以下操作:
shifted_end = df.groupby("Worker")["Shift_end"].shift()
df["Partial_break"] = (df["Shift_start"] - shifted_end)
df['Partial_break_hours'] = df["Partial_break"].dt.total_seconds() / 3600
df.loc[(df['Partial_break_hours']<0.33), 'Partial_break_hours'] = 0
但是我想不出一种方法来实现搜索逻辑以给出所需的输出。任何帮助都是非常感谢的!
2条答案
按热度按时间ie3xauqp1#
您可以尝试(假设DataFrame已排序):
图纸:
8tntrjer2#
你可以计算一个“fullBreakAtStart”标志,并在此基础上设置一个“lastShiftStart”,如果没有“fullBreakAtStart”,则只需输入一个
np.nan
,然后使用fillna(method="ffill")
函数,代码如下: