繁体   English   中英

条件为 pandas 的两行之间的时间

[英]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 做同样的事情。 有任何想法吗?

逻辑是:

  • 对于每个“工人”,找到他特别是 position 的时间段。如果有多行,则合并它们。
  • 将此与您的结果 df 结合起来,并使用与“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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM