基于任务创建时间统计各时刻在线与离线用户数量
任务创建时间点的在线/离线用户统计实现方案
问题背景
现有两个Pandas DataFrame:
df:存储用户登录、登出时间,数据如下:
| Login time | Logout time |
|---|---|
| 2022-08-01 11:30:00 | 2022-08-01 11:50:00 |
| 2022-08-01 11:35:00 | 2022-08-01 11:55:00 |
| 2022-08-01 11:35:00 | 2022-08-01 11:57:00 |
df2:存储任务创建时间,数据如下:
| created time |
|---|
| 2022-08-01 11:45:00 |
| 2022-08-01 11:51:00 |
| 2022-08-01 11:56:00 |
| 2022-08-01 11:57:00 |
| 2022-08-01 12:00:00 |
需要生成result_df,统计每个任务创建时间点对应的在线用户数(登录时间≤任务时间<登出时间)和离线用户数(总用户数-在线用户数),预期结果如下:
| created time | Online users | Offline users |
|---|---|---|
| 2022-08-01 11:45:00 | 3 | 0 |
| 2022-08-01 11:51:00 | 2 | 1 |
| 2022-08-01 11:56:00 | 1 | 2 |
| 2022-08-01 11:57:00 | 0 | 3 |
| 2022-08-01 12:00:00 | 0 | 3 |
实现步骤(Python Pandas)
1. 数据初始化与类型转换
首先将时间列转换为datetime类型,确保时间比较的准确性:
import pandas as pd # 初始化用户登录登出数据 df = pd.DataFrame({ 'Login time': ['2022-08-01 11:30:00', '2022-08-01 11:35:00', '2022-08-01 11:35:00'], 'Logout time': ['2022-08-01 11:50:00', '2022-08-01 11:55:00', '2022-08-01 11:57:00'] }) # 初始化任务创建时间数据 df2 = pd.DataFrame({ 'created time': ['2022-08-01 11:45:00', '2022-08-01 11:51:00', '2022-08-01 11:56:00', '2022-08-01 11:57:00', '2022-08-01 12:00:00'] }) # 转换时间列类型为datetime df['Login time'] = pd.to_datetime(df['Login time']) df['Logout time'] = pd.to_datetime(df['Logout time']) df2['created time'] = pd.to_datetime(df2['created time'])
2. 统计在线用户数
通过广播机制,对每个任务时间判断所有用户是否在线,再求和得到在线用户数:
# 计算每个任务时间对应的在线用户数 online_counts = df2['created time'].apply( lambda x: ((df['Login time'] <= x) & (x < df['Logout time'])).sum() ) df2['Online users'] = online_counts
3. 统计离线用户数
离线用户数等于总用户数减去在线用户数:
total_users = len(df) df2['Offline users'] = total_users - df2['Online users']
4. 生成结果DataFrame
最终的result_df就是处理后的df2,可以直接使用:
result_df = df2.copy() print(result_df)
运行后输出的结果与预期完全一致。
优化说明(大数据量场景)
如果用户数据量很大(比如上万条),上述apply方法效率较低,可以改用向量化的广播方式提升性能:
# 向量化实现,避免循环 created_times = df2['created time'].to_numpy()[:, None] login_times = df['Login time'].to_numpy() logout_times = df['Logout time'].to_numpy() # 生成布尔矩阵,每行对应一个任务时间,每列对应一个用户 is_online = (login_times <= created_times) & (created_times < logout_times) df2['Online users'] = is_online.sum(axis=1) df2['Offline users'] = total_users - df2['Online users']
这种方式利用numpy的广播特性,避免了逐行循环,性能提升明显。
内容的提问来源于stack exchange,提问作者Datalearner
相关产品推荐
相关产品推荐

