[英]Time between two rows with conditions in pandas
假设我们有一个 pandas dataframe 轮班:
df_aux = pd.DataFrame({'Worker' : ['Alice','Alice','Alice','Alice','Alice', 'Bob','Bob','Bob'],
'Shift_start' : ['2022-01-01 10:00:00', '2022-01-01 10:30:00', '2022-01-01 11:45:00', '2022-01-01 12:45:00', '2022-01-01 13:15:00', '2022-01-01 10:30:00', '2022-01-01 12:00:00', '2022-01-01 13:15:00'],
'Shift_end' : ['2022-01-01 10:15:00', '2022-01-01 11:45:00', '2022-01-01 12:30:00', '2022-01-01 13:15:00', '2022-01-01 14:00:00', '2022-01-01 11:30:00', '2022-01-01 13:10:00', '2022-01-01 14:30:00'],
'Position' : [1, 1, 2, 2, 2, 1, 2, 3],
'Role' : ['A', 'B', 'B', 'A', 'B', 'A', 'B', 'A']})
工人 | 换档开始 | Shift_end | Position | 角色 |
---|---|---|---|---|
爱丽丝 | 2022-01-01 10:00:00 | 2022-01-01 10:15:00 | 1个 | 一种 |
爱丽丝 | 2022-01-01 10:30:00 | 2022-01-01 11:45:00 | 1个 | 乙 |
爱丽丝 | 2022-01-01 11:45:00 | 2022-01-01 12:30:00 | 2个 | 乙 |
爱丽丝 | 2022-01-01 12:45:00 | 2022-01-01 13:15:00 | 2个 | 一种 |
爱丽丝 | 2022-01-01 13:15:00 | 2022-01-01 14:00:00 | 2个 | 乙 |
鲍勃 | 2022-01-01 10:30:00 | 2022-01-01 11:30:00 | 1个 | 一种 |
鲍勃 | 2022-01-01 12:00:00 | 2022-01-01 13:10:00 | 2个 | 乙 |
鲍勃 | 2022-01-01 13:15:00 | 2022-01-01 14:30:00 | 3个 | 一种 |
Position 列指的是工人所在的地方,而有两个角色,A 和 B(假设有主要和辅助,例如)。 我需要计算每个工人在当前 position 的时间,无论他们的角色如何,以及他们在某些事件发生时处于相同的 position 和角色的时间。 这些事件在一个df_main中给出,它记录了时间和position:
df_main = pd.DataFrame({'Event_time' : ['2022-01-01 11:05:00', '2022-01-01 12:35:00', '2022-01-01 13:25:00'] ,
'Position' : [1, 2, 2]})
事件_时间 | Position |
---|---|
2022-01-01 11:05:00 | 1个 |
2022-01-01 12:35:00 | 2个 |
2022-01-01 13:25:00 | 2个 |
这个想法是在 df_main 和 df_aux 之间执行合并以获得以下信息:
事件_时间 | 工人 | 换档开始 | Shift_end | Position | 角色 | 就位时间 | Time_in_position_role |
---|---|---|---|---|---|---|---|
2022-01-01 11:05:00 | 爱丽丝 | 2022-01-01 10:30:00 | 2022-01-01 11:45:00 | 1个 | 乙 | 1 小时 05 分钟 | 0 小时 35 分钟 |
2022-01-01 11:05:00 | 鲍勃 | 2022-01-01 10:30:00 | 2022-01-01 13:30:00 | 1个 | 一种 | 0 小时 35 分钟 | 0 小时 35 分钟 |
2022-01-01 12:35:00 | 鲍勃 | 2022-01-01 12:00:00 | 2022-01-01 15:10:00 | 2个 | 乙 | 0 小时 35 分钟 | 0 小时 35 分钟 |
2022-01-01 13:25:00 | 爱丽丝 | 2022-01-01 13:15:00 | 2022-01-01 14:00:00 | 2个 | 乙 | 1小时40分钟 | 0 小时 10 分钟 |
第一行是重复的,因为爱丽丝和鲍勃在事件发生时都在那个 position 中,但角色不同。 我设法计算了 Time_in_position_role 列:
df_full = df_main.merge(df_aux, on='Position')
df_full = df_full[(df_full['Event_time']>df_full['Shift_start']) & (df_full['Event_time']<df_full['Shift_end'])]
df_full['Time_in_position_role'] = df_full['Event_time'] - df_full['Shift_start']
但是我无法对 Time_in_position 做同样的事情。 有任何想法吗?
逻辑是:
# For each "Worker", find the time period for which he was in particular position. If there are multiple rows, then merge them.
def sort_n_rank(g):
df_g = g.apply(pd.Series)
df_g = df_g.sort_values(0)
return (df_g[1] != df_g[1].shift(1)).cumsum()
df_aux["start_position"] = df_aux[["Shift_start", "Position"]].apply(tuple, axis=1)
df_aux["rank"] = df_aux.groupby("Worker")[["start_position"]].transform(sort_n_rank)
df_worker_position = df_aux.groupby(["Worker", "rank"]) \
.agg( \
Shift_start_min = ("Shift_start", "min"),
Shift_end_max = ("Shift_end", "max"),
Position = ("Position", "first")
) \
.reset_index()
df_full = df_full.merge(df_worker_position, on=["Worker", "Position"])
df_full = df_full[(df_full["Event_time"] > df_full["Shift_start_min"]) & (df_full["Event_time"] < df_full["Shift_end_max"])]
df_full["Time_in_position"] = df_full["Event_time"] - df_full["Shift_start_min"]
Output:
Event_time Worker Shift_start Shift_end Position Role Time_in_position Time_in_position_role
0 2022-01-01 11:05:00 Alice 2022-01-01 10:30:00 2022-01-01 11:45:00 1 B 0 days 01:05:00 0 days 00:35:00
1 2022-01-01 11:05:00 Bob 2022-01-01 10:30:00 2022-01-01 11:30:00 1 A 0 days 00:35:00 0 days 00:35:00
2 2022-01-01 12:35:00 Bob 2022-01-01 12:00:00 2022-01-01 13:10:00 2 B 0 days 00:35:00 0 days 00:35:00
3 2022-01-01 13:25:00 Alice 2022-01-01 13:15:00 2022-01-01 14:00:00 2 B 0 days 01:40:00 0 days 00:10:00
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.