【问题标题】:Is there a vectorized parallel max() and min()?是否有矢量化并行 max() 和 min()?
【发布时间】:2011-08-01 06:52:12
【问题描述】:

我有一个data.frame,其中包含“a”和“b”列。我想添加名为“high”和“low”的列,其中包含列 a 和 b 中的最高值和最低值。

有没有一种方法可以在不循环数据帧中的行的情况下做到这一点?

编辑:这是针对 OHLC 数据的,因此高低列应包含同一行中 a 和 b 之间的最高和最低元素,而不是整个列中的最高和最低元素。如果措辞不当,请见谅。

【问题讨论】:

    标签: r parallel-processing vectorization max minimum


    【解决方案1】:

    这是我使用Rcpp 实现的版本。我将pmin与我的版本进行了比较,我的版本大约快了3倍。

    library(Rcpp)
    
    cppFunction("
      NumericVector min_vec(NumericVector vec1, NumericVector vec2) {
        int n = vec1.size();
        if(n != vec2.size()) return 0;
        else {
          NumericVector out(n);
          for(int i = 0; i < n; i++) {
            out[i] = std::min(vec1[i], vec2[i]);
          }
          return out;
        }
      }
    ")
    
    x1 <- rnorm(100000)
    y1 <- rnorm(100000)
    
    microbenchmark::microbenchmark(min_vec(x1, y1))
    microbenchmark::microbenchmark(pmin(x1, y1))
    
    x2 <- rnorm(500000)
    y2 <- rnorm(500000)
    
    microbenchmark::microbenchmark(min_vec(x2, y2))
    microbenchmark::microbenchmark(pmin(x2, y2))
    

    100,000 个元素的 microbenchmark 函数输出为:

    > microbenchmark::microbenchmark(min_vec(x1, y1))
    Unit: microseconds
                expr     min       lq     mean  median       uq
     min_vec(x1, y1) 215.731 222.3705 230.7018 224.484 228.1115
         max neval
     284.631   100
    > microbenchmark::microbenchmark(pmin(x1, y1))
    Unit: microseconds
             expr     min       lq     mean  median      uq      max
     pmin(x1, y1) 891.486 904.7365 943.5884 922.899 954.873 1098.259
     neval
       100
    

    对于 500,000 个元素:

    > microbenchmark::microbenchmark(min_vec(x2, y2))
    Unit: milliseconds
                expr      min       lq     mean   median       uq
     min_vec(x2, y2) 1.493136 2.008122 2.109541 2.140318 2.300022
         max neval
     2.97674   100
    > microbenchmark::microbenchmark(pmin(x2, y2))
    Unit: milliseconds
             expr      min       lq     mean   median       uq
     pmin(x2, y2) 4.652925 5.146819 5.286951 5.264451 5.445638
          max neval
     6.639985   100
    

    所以你可以看到Rcpp 版本更快。

    您可以通过在函数中添加一些错误检查来使其变得更好,例如:检查两个向量的长度是否相同,或者它们是否具有可比性(不是字符与数字,或布尔与数字)。

    【讨论】:

      【解决方案2】:

      另一种可能的解决方案:

      set.seed(21)
      Data <- data.frame(a=runif(10),b=runif(10))
      Data$low <- apply(Data[,c("a","b")], 1, min)
      Data$high <- apply(Data[,c("a","b")], 1, max)
      

      【讨论】:

      • 这仍然是连续的。
      【解决方案3】:

      如果你的 data.frame 名称是 dat。

      dat$pmin <- do.call(pmin,dat[c("a","b")])
      dat$pmax <- do.call(pmax,dat[c("a","b")])
      

      【讨论】:

        【解决方案4】:

        听起来您正在寻找pmaxpmin(“并行”最大/最小):

        Extremes                 package:base                  R Documentation
        
        Maxima and Minima
        
        Description:
        
             Returns the (parallel) maxima and minima of the input values.
        
        Usage:
        
             max(..., na.rm = FALSE)
             min(..., na.rm = FALSE)
        
             pmax(..., na.rm = FALSE)
             pmin(..., na.rm = FALSE)
        
             pmax.int(..., na.rm = FALSE)
             pmin.int(..., na.rm = FALSE)
        
        Arguments:
        
             ...: numeric or character arguments (see Note).
        
           na.rm: a logical indicating whether missing values should be
                  removed.
        
        Details:
        
             ‘pmax’ and ‘pmin’ take one or more vectors (or matrices) as
             arguments and return a single vector giving the ‘parallel’ maxima
             (or minima) of the vectors.  The first element of the result is
             the maximum (minimum) of the first elements of all the arguments,
             the second element of the result is the maximum (minimum) of the
             second elements of all the arguments and so on.  Shorter inputs
             are recycled if necessary.  ‘attributes’ (such as ‘names’ or
             ‘dim’) are transferred from the first argument (if applicable).
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-04
          • 1970-01-01
          • 2012-10-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多