如何使用Python测量每个组中的开始时间和结束时间是否有重叠?

bgibtngc  于 2023-02-18  发布在  Python
关注(0)|答案(2)|浏览(168)

如何查看每个组(按ID)的开始时间和/或结束时间之间是否存在重叠。也就是说,是否有两个“服务”从一个员工(ID)开始在任意时间长度内同时发生。我有一个如下所示的表,但希望计算重叠列。

| ID |   Begin Time   |    End Time    | Overlap |
| 1  | 1/1/2023 13:30 | 1/1/2023 13:55 |  False  |
| 1  | 1/7/2023 12:30 | 1/1/2023 13:45 |  False  |
| 2  | 1/3/2023 15:30 | 1/3/2023 16:30 |   True  |
| 1  | 1/5/2023 07:30 | 1/5/2023 08:30 |   True  |
| 2  | 1/3/2023 14:55 | 1/3/2023 15:55 |   True  |
| 1  | 1/5/2023 06:30 | 1/5/2023 09:30 |   True  |
| 1  | 1/7/2023 06:30 | 1/7/2023 09:30 |   True  |
| 1  | 1/7/2023 06:00 | 1/7/2023 06:45 |   True  |

下面是创建此 Dataframe 的代码块--〉

id_list = [1,1,2,1,2,1,1,1]
begin_time = ['1/1/2023 13:30', '1/7/2023 12:30', '1/3/2023 15:30', '1/5/2023 07:30', '1/3/2023 14:55', 
             '1/5/2023 06:30', '1/7/2023 06:30', '1/7/2023 06:00']
end_time = ['1/1/2023 13:55', '1/1/2023 13:45', '1/3/2023 16:30', '1/5/2023 08:30', '1/3/2023 15:55',
           '1/5/2023 09:30', '1/7/2023 09:30', '1/7/2023 06:45']
df = pd.DataFrame(list(zip(id_list, begin_time, end_time)), columns = ['ID', 'Begin_Time', 'End_Time'])
df['Begin_Time'] = pd.to_datetime(df['Begin_Time'])
df['End_Time'] = pd.to_datetime(df['End_Time'])
df
vjhs03f7

vjhs03f71#

在自定义函数中使用Interval.overlaps,枚举以筛选出自身Interval

def f(x):
    i = pd.IntervalIndex.from_arrays(x['Begin_Time'],
                                     x['End_Time'], 
                                 closed="both")
    a = np.arange(len(x))
    x['overlap'] = [i[a != j].overlaps(y).any() for j, y in enumerate(i) ]
    return x

df = df.groupby('ID').apply(f)
print (df)
   ID          Begin_Time            End_Time  overlap
0   1 2023-01-01 13:30:00 2023-01-01 13:55:00    False
1   1 2023-01-08 12:30:00 2023-01-08 13:45:00    False <- data was changed
2   2 2023-01-03 15:30:00 2023-01-03 16:30:00     True
3   1 2023-01-05 07:30:00 2023-01-05 08:30:00     True
4   2 2023-01-03 14:55:00 2023-01-03 15:55:00     True
5   1 2023-01-05 06:30:00 2023-01-05 09:30:00     True
6   1 2023-01-07 06:30:00 2023-01-07 09:30:00     True
7   1 2023-01-07 06:00:00 2023-01-07 06:45:00     True
tv6aics1

tv6aics12#

首先,按照ID和开始_Time对 Dataframe 进行排序,以确保每个ID的所有行都按时间顺序分组在一起。

df = df.sort_values(['ID', 'Begin_Time'])

定义一个名为“Next_开始_Time”的新列,该列保存具有相同ID的下一个服务的Begin_Time。您可以使用shift()函数创建一个新列,该列的值与Begin_Time相同,但下移一行,然后按ID分组。

df['Next_Begin_Time'] = df.groupby('ID')['Begin_Time'].shift(-1)

定义一个名为“Overlap”的新列,当服务的End_Time晚于同一ID的下一个服务的开始_Time时,该列为True,否则为False。可以使用简单的比较来创建布尔列。

df['Overlap'] = (df['End_Time'] > df['Next_Begin_Time']).fillna(False)

生成的 Dataframe 将有一个名为“重叠”的附加列,当存在重叠时显示True,否则显示False

相关问题