【问题标题】:Fastest way to take the weighted sum of the columns of a matrix in R在R中获取矩阵列的加权和的最快方法
【发布时间】:2012-10-28 04:57:01
【问题描述】:

我需要矩阵每一列的加权和。

data <- matrix(1:2e7,1e7,2) # warning large number, will eat up >100 megs of memory
weights <- 1:1e7/1e5
system.time(colSums(data*weights))
system.time(apply(data,2,function(x) sum(x*weights)))
all.equal(colSums(data*weights), apply(data,2,function(x) sum(x*weights)))

通常colSums(data*weights) 比应用调用更快。

我经常做这个操作(在一个大矩阵上)。因此,寻求有关最有效实施的建议。理想情况下,如果我们可以将权重传递给 colSums(或 rowSums),那就太好了。

谢谢,感谢任何见解!

【问题讨论】:

    标签: r sum weighted


    【解决方案1】:

    colSums* 都是内部或原始函数,将比 apply 方法快得多

    您可以尝试的另一种方法是在寻找时使用一些基本的矩阵代数

     weights %*% data
    

    矩阵乘法的方法看起来并不快但是会避免创建一个大小为data的临时对象

    system.time({.y <- colSums(data * weights)})
    ##  user  system elapsed 
    ##  0.12    0.03    0.16 
    
    
    system.time({.x <- weights %*% data})
    ##   user  system elapsed 
    ##   0.20    0.05    0.25 
    

    【讨论】:

      【解决方案2】:

      Rcpp 会带来性能提升(尤其是在列数较多的情况下)。

      library(Rcpp)
      library(inline)
      src <- '
       Rcpp::NumericMatrix dataR(data);
       Rcpp::NumericVector weightsR(weights);
       int ncol = dataR.ncol();
       Rcpp::NumericVector sumR(ncol);
       for (int col = 0; col<ncol; col++){
         sumR[col] = Rcpp::sum(dataR( _, col)*weightsR);
       }
       return Rcpp::wrap(sumR);'
      
      weighted.colSums <- cxxfunction(
        signature(data="numeric", weights="numeric"), src, plugin="Rcpp")
      data <- matrix(as.numeric(1:1e7),1e5,100) # warning large object
      weights <- 1:1e5/1e5
      all.equal(colSums(data*weights), weighted.colSums(data, weights))
      ## [1] TRUE
      print(system.time(colSums(data*weights)))
      ##   user  system elapsed 
      ##  0.065   0.001   0.064 
      print(system.time(as.vector(weighted.colSums(data, weights))))
      ##   user  system elapsed 
      ##  0.019   0.001   0.019 
      all.equal(as.vector(weights %*% data), weighted.colSums(data, weights))
      ## [1] TRUE
      print(system.time(weights %*% data))
      ##   user  system elapsed 
      ##  0.066   0.001   0.066 
      

      【讨论】:

        猜你喜欢
        • 2012-11-20
        • 1970-01-01
        • 2016-08-24
        • 1970-01-01
        • 1970-01-01
        • 2020-08-07
        • 2018-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多