将当前行值与前一行值进行比较

Sar*_*thy 8 python dataframe pandas

我有来自用户 A 一天的登录历史数据。我的要求是用户 A 在任何时候都只能有一个有效的登录名。在下面的示例中,用户可能多次尝试成功登录,而他的第一个会话仍处于活动状态。因此,在有效会话期间发生的任何登录都需要标记为重复。

示例 1:

在下面的第一个示例数据中,当用户仍然从00:12:38to01:00:02 (index 0)登录时,用户在00:55:14to处进行了另一个登录01:00:02 (index 1)

同样,如果我们比较index 23,我们可以看到记录 atindex 3是根据要求重复登录。

  start_time  end_time
0   00:12:38  01:00:02
1   00:55:14  01:00:02
2   01:00:02  01:32:40
3   01:00:02  01:08:40
4   01:41:22  03:56:23
5   18:58:26  19:16:49
6   20:12:37  20:52:49
7   20:55:16  22:02:50
8   22:21:24  22:48:50
9   23:11:30  00:00:00
Run Code Online (Sandbox Code Playgroud)

预期输出:

  start_time  end_time   isDup
0   00:12:38  01:00:02       0
1   00:55:14  01:00:02       1
2   01:00:02  01:32:40       0
3   01:00:02  01:08:40       1
4   01:41:22  03:56:23       0
5   18:58:26  19:16:49       0
6   20:12:37  20:52:49       0
7   20:55:16  22:02:50       0
8   22:21:24  22:48:50       0
9   23:11:30  00:00:00       0
Run Code Online (Sandbox Code Playgroud)

这些重复记录需要在 column 更新为 1 isDup


示例 2:

另一个数据示例如下。在这里,虽然用户仍然在13:36:10和之间登录13:50:16,但还有 3 个额外的会话需要标记。

  start_time  end_time
0   13:32:54  13:32:55
1   13:36:10  13:50:16
2   13:37:54  13:38:14
3   13:46:38  13:46:45
4   13:48:59  13:49:05
5   13:50:16  13:50:20
6   14:03:39  14:03:49
7   15:36:20  15:36:20
8   15:46:47  15:46:47
Run Code Online (Sandbox Code Playgroud)

预期输出:

  start_time    end_time    isDup
0   13:32:54    13:32:55    0
1   13:36:10    13:50:16    0
2   13:37:54    13:38:14    1
3   13:46:38    13:46:45    1
4   13:48:59    13:49:05    1
5   13:50:16    13:50:20    0
6   14:03:39    14:03:49    0
7   15:36:20    15:36:20    0
8   15:46:47    15:46:47    0
Run Code Online (Sandbox Code Playgroud)

将当前记录的开始时间与以前的记录进行比较的有效方法是什么?

Shu*_*rma 2

time列中的类似值映射到 pandas对象start_time,并从列中的 timedelta 值中减去。end_timeTimeDelta1 seconds00:00:00end_time

c = ['start_time', 'end_time']
s, e = df[c].astype(str).apply(pd.to_timedelta).to_numpy().T
e[e == pd.Timedelta(0)] += pd.Timedelta(days=1, seconds=-1)
Run Code Online (Sandbox Code Playgroud)

然后,对于数据帧中的每对start_time和 ,使用以下方法标记相应的重复间隔:end_timedfnumpy broadcasting

m = (s[:, None] >= s) & (e[:, None] <= e)
np.fill_diagonal(m, False)
df['isDupe'] = (m.any(1) & ~df[c].duplicated(keep=False)).view('i1')
Run Code Online (Sandbox Code Playgroud)
# example 1
  start_time  end_time  isDupe
0   00:12:38  01:00:02       0
1   00:55:14  01:00:02       1
2   01:00:02  01:32:40       0
3   01:00:02  01:08:40       1
4   01:41:22  03:56:23       0
5   18:58:26  19:16:49       0
6   20:12:37  20:52:49       0
7   20:55:16  22:02:50       0
8   22:21:24  22:48:50       0
9   23:11:30  00:00:00       0

# example 2
  start_time  end_time  isDupe
0   13:32:54  13:32:55       0
1   13:36:10  13:50:16       0
2   13:37:54  13:38:14       1
3   13:46:38  13:46:45       1
4   13:48:59  13:49:05       1
5   13:50:16  13:50:20       0
6   14:03:39  14:03:49       0
7   15:36:20  15:36:20       0
8   15:46:47  15:46:47       0
Run Code Online (Sandbox Code Playgroud)