我正在尝试找到用几个数字列子集大数据集的最快方法。正如data.table所promise的,进行二进制搜索所需的时间比矢量扫描快得多。但是,二进制搜索需要事先执行setkey。正如您在这段代码中看到的,它需要非常长的时间!一旦您考虑到这段时间,矢量扫描就快得多:
set.seed(1)
n=10^7
nums <- round(runif(n,0,10000))
DT = data.table(s=sample(nums,n), exp=sample(nums,n),
init=sample(nums,n), contval=sample(nums,n))
this_s = DT[0.5*n,s]
this_exp = DT[0.5*n,exp]
this_init = DT[0.5*n,init]
system.time(ans1<-DT[s==this_s&exp==this_exp&init==this_init,4,with=FALSE])
# user system elapsed
# 0.65 0.01 0.67
system.time(setkey(DT,s,exp,init))
# user system elapsed
# 41.56 0.03 41.59
system.time(ans2<-DT[J(this_s,this_exp,this_init),4,with=FALSE])
# user system elapsed
# 0 0 0
identical(ans1,ans2)
# [1] TRUE
我做错了什么吗?我已经阅读了data.table常见问题解答等。任何帮助都将不胜感激。
非常感谢。
该行:
nums <- round(runif(n,0,10000))
将数字
保留为类型数字
而不是整数
。这有很大的不同。数据表常见问题解答和介绍面向整数
和字符
列;在这些类型上,您不会看到 setkey
很慢。例如:
nums <- as.integer(round(runif(n,0,10000)))
...
setkey(DT,s,exp,init) # much faster now
还有两点...
首先,在当前的数据开发版本中,排序/排序操作要快得多。表v1.8.11。@jihoward关于数字列的排序是一个更耗时的操作的观点是正确的。但是,在1.8.11中,它仍然快了大约5-8倍(因为实现了6次基数顺序,请查看本文)。比较1.8.10和1.8.11中<code>设置键<code>操作所需的时间:
# v 1.8.11
system.time(setkey(DT,s,exp,init))
# user system elapsed
# 8.358 0.375 8.844
# v 1.8.10
system.time(setkey(DT,s,exp,init))
# user system elapsed
# 66.609 0.489 75.216
这是我的系统8.5倍的改进。所以,我的猜测是,这大约需要4.9秒。
第二,正如@Roland提到的,如果你的目标是执行几个子集化,而这就是你要做的全部,那么当然做setkey是没有意义的,因为它必须找到列的顺序,然后重新排序整个data.table(通过引用,以便内存占用非常少,查看这篇文章了解更多关于setkey的信息)。
我有一个严格按递减顺序排序的数组和一个元素;我想找到数组中最大元素的索引,该元素小于val(如果val已经存在,则为相等),并且我想在时间内完成此操作。和执行upper_bound()不是一个选项。 例如,如果数组为{10,5,3,1}而val为6,则函数应返回1。 我对迭代器是个新手,尝试过在upper_bound()中添加比较函数来使其工作,但失败了。我该怎么处理这件事。 注意:我检查了类似的
问题内容: 程序从经过排序的字符串的txt文件中读取,并使用顺序的,迭代的二进制和递归的二进制存储在数组中,然后在数组中搜索位置以及查找该单词所需的迭代次数。当我尝试将数组中的单词与用户输入的单词进行比较时出现错误。不知道为什么。2)希望有人可以解释迭代二进制和递归二进制之间的区别。3)为什么需要这样做… SearchString si = new SearchString(); 程序在下面… }
问题内容: 我知道索引在内部是B树或类似的树结构。假设索引是为3列构建的,我希望Postgres执行以下操作: 在该B树中找到键[a = 10,b = 20,c = 30], 扫描下10个条目并返回它们。 如果索引只有一列,则解决方案显而易见: 但是,如果有更多的列,解决方案将变得更加复杂。对于2列: 3栏: 请注意查询: 是 不正确的 ,因为它将例如过滤掉[a = 11,b = 10,c = 1
二进制搜索是一种快速搜索算法,运行时复杂度为Ο(log n)。 这种搜索算法的工作原则是分而治之。 为使此算法正常工作,数据收集应采用排序形式。 二进制搜索通过比较集合的最中间项来查找特定项。 如果匹配发生,则返回项目的索引。 如果中间项大于项,则在中间项左侧的子阵列中搜索项。 否则,在中间项右侧的子阵列中搜索项。 该过程也在子阵列上继续,直到子阵列的大小减小到零。 二进制搜索如何工作? 要使二进
给定二叉查找树(BST)和整数val的根。 在BST中找到该节点的值等于val的节点,并返回以该节点为根的子树。如果这样的节点不存在,则返回null。 为什么'ans=root'不起作用??
问题内容: 我有一个排序的数组,想要对它进行二进制搜索。 所以我想问一下Swift库中是否已有诸如sort等的东西?还是有类型独立版本可用? 当然,我可以自己编写它,但是我想避免再次发明轮子。 问题答案: 这是使用二进制搜索的通用方法: