- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个用户登录和注销表。
表格看起来像这样但是有几十万行:
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'], dtype='datetime64[ns]')
我能够使用 for 循环以一种 hacky 的方式解决这个问题。它在较小的数据集上运行良好,但在 30 万行上需要数小时。
基本上,这段代码计算每个 session ( session 是每一行)同时登录的用户数
这是我的解决方案。它给出了我需要的结果。我也可以通过使用 apply 编写 lambda 来实现同样的效果,但需要更长的时间。
# create a new column for simultaneous
df_test['simultaneous'] = 0
start_time = time.time()
# loop through dataframe and check condition
for i in df_test.index:
login, logout = df_test.loc[i,'login'], df_test.loc[i,'logout']
this_index = df_test.index.isin([i])
df_test.loc[i, 'simultaneous'] = int(sum(
(df_test[~this_index]['login'] <= logout) & (df_test[~this_index]['logout'] >= login)
))
print("--- %s seconds ---" % (time.time() - start_time))
能否请您看看并告诉我是否有更好的方法来获得相同的结果。也许我遗漏了一些明显的东西。
提前致谢!
最佳答案
此算法基于此数据按登录时间排序这一事实采用流式处理方法。对于每个 session ,它会跟踪注销时间尚未过去的所有 session 的计数(只需将注销时间存储在列表中,并在每次检查新 session 时从该列表中删除陈旧的条目)。我决定将 sess1.logout==sess2.login 计为同时发生,但如果您不同意,可以将 >=
更改为 >
。
算法在calculate
函数中。
#!/usr/bin/python
import datetime
import random
import time
from statistics import mean, stdev
def calculate(data):
active_sessions = []
simultaneous_sessions = []
for user_id, login, logout in data:
active_sessions = [ts for ts in active_sessions if ts >= login]
simultaneous_sessions.append(len(active_sessions))
active_sessions.append(logout)
return simultaneous_sessions
def generate_data(numsessions):
start_time = datetime.datetime(2020, 5, 13, 0, 0, 1)
data = []
while len(data) < numsessions:
for cnt in range(random.choice([0, 0, 0, 1, 1, 2, 3])):
user_id = chr(ord("a") + cnt) * 2
duration = random.choice([30, 30, 60, 90, 90, 900, 1800])
logout_time = start_time + datetime.timedelta(seconds=duration)
data.append(
(
user_id,
start_time.strftime("%Y-%m-%d %H:%M:%S"),
logout_time.strftime("%Y-%m-%d %H:%M:%S"),
)
)
start_time += datetime.timedelta(minutes=1)
return data
start_time = time.time()
num_sessions = 3 * 1e5 # 300,000
print(f"generating data for {num_sessions:.0f} sessions")
data = generate_data(num_sessions)
print(f"sample data=[{data[0]}]")
print("--- %.2f seconds ---" % (time.time() - start_time))
start_time = time.time()
print("calculating simultaneous sessions")
simultaneous_sessions = calculate(data)
print(
"for {} sessions have max={} min={}, mean={:.2f} stdev={:.2f}".format(
len(simultaneous_sessions),
max(simultaneous_sessions),
min(simultaneous_sessions),
mean(simultaneous_sessions),
stdev(simultaneous_sessions),
)
)
print("--- %.2f seconds ---" % (time.time() - start_time))
从性能的角度来看,我遍历了一次列表,同时不断地重新创建 active_sessions 列表,只要 active_sessions 是一个小数字,就会很快。您可以通过更高效的 active_sessions 列表进行其他优化,但这应该比搜索每个 session 的所有数据快得多。即使数据未按登录时间排序,我认为按登录时间排序然后使用此算法比为每个 session 扫描所有 session 更有效。
更新:我添加了一个合成数据生成器,它基于一些随机变量创建了一堆 session 。这表明该算法处理 30 万行所需的时间不到一秒。
对于 30 万个 session ,大约需要 0.4 秒:
generating data for 300000 sessions
sample data=[('aa', '2020-05-13 00:02:01', '2020-05-13 00:03:31')]
--- 1.99 seconds ---
calculating simultaneous sessions
for 300001 sessions have max=26 min=0, mean=7.42 stdev=2.76
--- 0.35 seconds ---
对于 300 万个 session ,大约需要 4 秒:
generating data for 3000000 sessions
sample data=[('aa', '2020-05-13 00:00:01', '2020-05-13 00:01:31')]
--- 19.35 seconds ---
calculating simultaneous sessions
for 3000001 sessions have max=26 min=0, mean=7.43 stdev=2.77
--- 3.93 seconds ---
O(N)
关于python - 在python中按用户计算并发 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73859886/
SQL 和一般开发的新手,我有一个表(COUNTRIES),其中包含字段(INDEX、NAME、POPULATION、AREA) 通常我添加一个客户端(Delphi)计算字段(DENSITY)和 On
我想使用 calc(100%-100px),但在我的 demo 中不起作用由于高度只接受像素,因此如何将此百分比值转换为像素。 最佳答案 以下将为您提供高度: $(window).height();
我正在尝试在 MySQL 中添加列并动态填充其他列。 例如我有一张表“数字”并具有第 1 列、第 2 列、第 3 列,这些总数应填充在第 4 列中 最佳答案 除非我误解了你的问题,否则你不只是在寻找:
我想返回简单计算的结果,但我不确定如何执行此操作。我的表格如下: SELECT COUNT(fb.engineer_id) AS `total_feedback`, SUM(fb.ra
我一直在尝试做这个程序,但我被卡住了,我仍然是一个初学者,任何帮助将不胜感激。我需要程序来做 打印一个 10 X 10 的表格,其中表格中的每个条目都是行号和列号的总和 包含一个累加器,用于计算所有表
这个计算背后一定有一些逻辑。但我无法得到它。普通数学不会导致这种行为。谁能帮我解释一下原因 printf ("float %f\n", 2/7 * 100.0); 结果打印 1.000000 为什么会
我想计算从 0 到 (n)^{1/2} - 1 的数字的 AND每个数字从 0 到 (n)^{1/2} - 1 .我想在 O(n) 中执行此操作时间,不能使用 XOR、OR、AND 运算。 具体来说,
如何在 Excel 中将公式放入自定义数字格式?例如(出于说明目的随机示例), 假设我有以下数据: 输入 输出 在不编辑单元格中的实际数据的情况下,我想显示单元格中的值除以 2,并保留两位小数: 有没
每次我在 Flutter 应用程序中调用计算()时,我都会看到内存泄漏,据我所知,这基本上只是一种生成隔离的便捷方法。我的应用程序内存占用增加并且在 GC 之后永远不会减少。 我已将我的代码简化为仅调
我有数字特征观察 V1通过 V12用于目标变量 Wavelength .我想计算 Vx 之间的 RMSE列。数据格式如下。 每个变量“Vx”以 5 分钟的间隔进行测量。我想计算所有 Vx 变量的观测值
我正在寻找一种使用 C 语言计算文件中未知字符数的简单方法。谢谢你的帮助 最佳答案 POSIX 方式(可能是您想要的方式): off_t get_file_length( FILE *file ) {
我正在使用 Postgres,并且我正试图围绕如何在连续日期跨度中得出第一个开始日期的问题进行思考。例如 :- ID | Start Date | End Date =================
我有一个订单表格,我在其中使用 jQuery 计算插件来汇总总数。 此求和工作正常,但生成的“总和”存在问题。总之,我希望用逗号替换任何点。 代码的基础是; function ($this) {
我在使用 double 变量计算简单算术方程时遇到问题。 我有一个具有 double 属性 Value 的组件,我将此属性设置为 100。 然后我做一个简单的减法来检查这个值是否真的是 100: va
我在这里看到了一些关于 CRC 32 计算的其他问题。但没有一个让我满意,因此是这样。 openssl 库是否有任何用于计算 CRC32 的 api 支持?我已经在为 SHA1 使用 openssl,
当我在PHP日期计算中遇到问题时,我感到惊讶。 $add = '- 30 days'; echo date('Y-m-01', strtotime($add)); // result is 2017-
我正在使用 javascript 进行练习,我编写了这个脚本来计算 2 个变量的总和,然后在第三个方程中使用这个总和!关于如何完成这项工作的任何想法都将非常有用! First Number:
我有一个来自EAC的提示单和一个包含完整专辑的FLAC文件。 我正在尝试制作一些python脚本来播放文件,因为我需要能够设置在flac文件中开始的位置。 如何从CueSheet格式MM:SS:FF转
这个问题已经有答案了: Adding two numbers concatenates them instead of calculating the sum (24 个回答) 已关闭去年。 我有一个
4000 我需要上面字段 name="quantity" 和 id="price" 中的值,并使用 javascript 函数进行计算,并将其显示在字段 id= 中仅当我单击计算按钮时才显示“总
我是一名优秀的程序员,十分优秀!