下表显示了给定软件的登录和注销时间。
USER_NAME USER_ROLE GMT_LOGIN_TIME GMT_LOGOUT_TIME LOGIN_DURATION
ABCD SUP_235 2017-12-15 11:05:25 2017-12-15 11:09:01 216.0
ABCE SUP_235 2017-12-15 11:23:14 2017-12-15 11:33:17 603.0
ABCF USER_285 2017-12-15 11:44:12 2017-12-15 12:07:52 1420.0
ABCG SUP_230 2017-12-15 18:43:17 2017-12-15 19:00:20 1023.0
ABCH USER_245 2017-12-15 10:36:59 2017-12-15 11:42:00 3901.0
如何识别并发用户?我将不得不在Python中执行此操作,但我并不担心该编程语言中的实现。我想了解逻辑本身。
在上面的示例中,用户ABCD,ABCE和ABCH是唯一的同步。
答案 0 :(得分:1)
以下是使用pandas
:
from StringIO import StringIO
# read data into dataframe
data = StringIO("""USER_NAME,USER_ROLE,GMT_LOGIN_TIME,GMT_LOGOUT_TIME,LOGIN_DURATION
ABCD,SUP_235,2017-12-15 11:05:25,2017-12-15 11:09:01,216.0
ABCE,SUP_235,2017-12-15 11:23:14,2017-12-15 11:33:17,603.0
ABCF,USER_285,2017-12-15 11:44:12,2017-12-15 12:07:52,1420.0
ABCG,SUP_230,2017-12-15 18:43:17,2017-12-15 19:00:20,1023.0
ABCH,USER_245,2017-12-15 10:36:59,2017-12-15 11:42:00,3901.0""")
df = pd.read_csv(data, sep=",")
# create a new column for simultaneous
df['simultaneous'] = 0
# loop through dataframe and check condition
for i in df.index:
login, logout = df.loc[i,'GMT_LOGIN_TIME'], df.loc[i,'GMT_LOGOUT_TIME']
this_index = df.index.isin([i])
df.loc[i, 'simultaneous'] = int(any(
(df[~this_index]['GMT_LOGIN_TIME'] <= logout) & (df[~this_index]['GMT_LOGOUT_TIME'] >= login)
))
输出:
USER_NAME USER_ROLE GMT_LOGIN_TIME GMT_LOGOUT_TIME \
0 ABCD SUP_235 2017-12-15 11:05:25 2017-12-15 11:09:01
1 ABCE SUP_235 2017-12-15 11:23:14 2017-12-15 11:33:17
2 ABCF USER_285 2017-12-15 11:44:12 2017-12-15 12:07:52
3 ABCG SUP_230 2017-12-15 18:43:17 2017-12-15 19:00:20
4 ABCH USER_245 2017-12-15 10:36:59 2017-12-15 11:42:00
LOGIN_DURATION simultaneous
0 216.0 1
1 603.0 1
2 1420.0 0
3 1023.0 0
4 3901.0 1
这是正确的,因为ABCD
和ABCE
都与ABCH
同时发生。
逻辑解释:
我们遍历数据框的每个index
(行)并抓取该用户的login
和logout
次。
接下来,我们要检查所有其他行的重叠,因此我们创建this_index
作为索引器以指向当前行。使用按位反转运算符(~
),我们可以选择df[~this_index]
的其他行。
对于其他行,我们使用any
函数检查其中是否有任何行符合overlap condition。由于这会返回boolean
,我们会转换为int
。如果您想查看有多少其他连接与此重叠,我们也可以使用sum(condition)
。
int(any(condition))
的结果放在'simultaneous'
列中。
有关重叠时间范围背后的逻辑,请参阅此页: Determine Whether Two Date Ranges Overlap
对于大型表,在pandas中循环遍历的速度很慢。这是一种使用pandas.Dataframe.apply()
获得相同结果的方法,它应该更快。
df['simultaneous'] = df.apply(
lambda x: int(
any(
(df[df['USER_NAME'] != x['USER_NAME']]['GMT_LOGIN_TIME'] <= x['GMT_LOGOUT_TIME']) &\
(df[df['USER_NAME'] != x['USER_NAME']]['GMT_LOGOUT_TIME'] >= x['GMT_LOGIN_TIME'])
)
),
axis=1
)