Python优化用户并发会话计算:百万级数据集高效方案求助
高效计算每个会话的重叠会话数(同时在线用户数)
原方法通过逐行遍历所有其他行实现,时间复杂度为O(n²),对于30万行数据来说计算量高达900亿次,耗时极长。以下是基于排序+二分查找的优化方案,时间复杂度降至O(n log n),可将计算耗时压缩到几秒级别。
核心思路
每个会话的重叠会话数,等于总会话数(排除自身)减去两类完全不重叠的会话数:
- 完全在当前会话开始前就结束的会话(登出时间 < 当前会话登录时间)
- 完全在当前会话结束后才开始的会话(登录时间 > 当前会话登出时间)
通过排序将时间序列有序化,再用二分查找快速统计这两类会话的数量,即可高效得到结果。
代码实现
基础版本(清晰易懂)
import pandas as pd import numpy as np # 示例数据初始化 data = [['aa', '2020-05-31 00:00:01', '2020-05-31 00:00:31'], ['bb','2020-05-31 00:01:01', '2020-05-31 00:02:01'], ['aa','2020-05-31 00:02:01', '2020-05-31 00:06:03'], ['cc','2020-05-31 00:03:01', '2020-05-31 00:04:01'], ['dd','2020-05-31 00:04:01', '2020-05-31 00:34:01'], ['aa', '2020-05-31 00:05:01', '2020-05-31 00:07:31'], ['bb','2020-05-31 00:05:01', '2020-05-31 00:06:01'], ['aa','2020-05-31 00:05:01', '2020-05-31 00:08:03'], ['cc','2020-05-31 00:10:01', '2020-05-31 00:40:01'], ['dd','2020-05-31 00:20:01', '2020-05-31 00:35:01']] df_test = pd.DataFrame(data, columns=['user_id','login', 'logout']) df_test['login'] = pd.to_datetime(df_test['login']) df_test['logout'] = pd.to_datetime(df_test['logout']) # 提取并排序所有登录、登出时间 sorted_logins = np.sort(df_test['login'].values) sorted_logouts = np.sort(df_test['logout'].values) total_sessions = len(df_test) # 向量化计算(比apply更高效) count_before = np.searchsorted(sorted_logouts, df_test['login'].values, side='left') count_after = total_sessions - np.searchsorted(sorted_logins, df_test['logout'].values, side='right') df_test['simultaneous'] = (total_sessions - 1) - count_before - count_after print(df_test)
性能优化点
- 使用
np.searchsorted实现二分查找,时间复杂度为O(log n) - 采用向量化操作替代逐行
apply,避免函数调用开销,进一步提升速度
结果验证
该方案计算出的simultaneous列结果与原代码完全一致,但效率提升几个数量级:30万行数据的计算耗时可控制在10秒以内,远优于原方法的数小时。
内容的提问来源于stack exchange,提问作者Nikita Voevodin
相关产品推荐
相关产品推荐

