小编典典

在向量或列中查找第二(第三...)最高/最低值的最快方法

all

R 提供了最大值和最小值,但除了对整个向量进行排序然后从该向量中选择一个值 x 之外,我没有看到一种真正快速的方法来按顺序找到另一个值。

例如,有没有更快的方法来获得第二高的价值?


阅读 74

收藏
2022-07-31

共1个答案

小编典典

Rfast 有一个名为 nth_element 的函数,它完全按照您的要求执行。

此外,上面讨论的基于部分排序的方法不支持查找 k个 最小值

免责声明 :处理整数时似乎会出现一个问题,可以通过使用 as.numeric 绕过(例如 Rfast::nth(as.numeric(1:10),
2)),并将在 Rfast 的下一次更新中解决.

Rfast::nth(x, 5, descending = T)

将返回 x 的第 5 大元素,而

Rfast::nth(x, 5, descending = F)

将返回 x 的第 5 个最小元素

下面针对最受欢迎的答案进行基准测试。

对于 10,000 个数字:

N = 10000
x = rnorm(N)

maxN <- function(x, N=2){
    len <- length(x)
    if(N>len){
        warning('N greater than length(x).  Setting N=length(x)')
        N <- length(x)
    }
    sort(x,partial=len-N+1)[len-N+1]
}

microbenchmark::microbenchmark(
Rfast = Rfast::nth(x,5,descending = T),
maxn = maxN(x,5),
order = x[order(x, decreasing = T)[5]])

Unit: microseconds
  expr      min       lq      mean   median        uq       max neval
 Rfast  160.364  179.607  202.8024  194.575  210.1830   351.517   100
  maxN  396.419  423.360  559.2707  446.452  487.0775  4949.452   100
 order 1288.466 1343.417 1746.7627 1433.221 1500.7865 13768.148   100

对于 100 个数字:

N = 1e6
x = rnorm(N)

microbenchmark::microbenchmark(
Rfast = Rfast::nth(x,5,descending = T),
maxN = maxN(x,5),
order = x[order(x, decreasing = T)[5]])

Unit: milliseconds
  expr      min        lq      mean   median        uq       max neval
 Rfast  89.7722  93.63674  114.9893 104.6325  120.5767  204.8839   100
  maxN 150.2822 207.03922  235.3037 241.7604  259.7476  336.7051   100
 order 930.8924 968.54785 1005.5487 991.7995 1031.0290 1164.9129   100
2022-07-31