与big.matrix一起运作

时间:2017-02-08 11:28:29

标签: r r-bigmemory bigdata

我必须使用big.matrix对象,我无法计算某些功能。让我们考虑以下big.matrix:

let(:image) { File.new('path/to/img.jpg') }

# Then in the test...

user.update(avatar: image)

相应的矩阵对象是:

# create big.matrix object
x <- as.big.matrix(
      matrix( sample(1:10, 20, replace=TRUE), 5, 4,
           dimnames=list( NULL, c("a", "b", "c", "d")) ) )

> x
An object of class "big.matrix"
Slot "address":
<pointer: 0x00000000141beee0>

如果我用矩阵对象计算这个操作,它可以工作:

# create matrix object

x2<-x[,]

> x2
     a b  c  d
[1,] 6 9  5  3
[2,] 3 6 10  8
[3,] 7 1  2  8
[4,] 7 8  4 10
[5,] 6 3  6  4

如果我使用big.matrix对象(事实上我必须使用它),它不起作用:

sqrt(slam::col_sums(x2*x2))

> sqrt(slam::col_sums(x2*x2))
       a        b        c        d 
13.37909 13.82027 13.45362 15.90597 

问题是2:*操作(创建矩阵的每个元素的平方),这会产生错误:

  

x * x中的错误:非数字参数转换为二元运算符

和sqrt函数,它产生错误:

  

sqrt(x)中的错误:数学函数的非数字参数。

如何使用big.matrix对象计算此操作?

2 个答案:

答案 0 :(得分:1)

使用@NgModule({ imports: [RouterModule.forChild([ { path: Constants.DASHBOARDROUTE, component: DashboardComponent} ])], exports: [RouterModule] }) export class DashboardRoutingModule {} 个对象,我找到了两个提供良好性能的解决方案:

  • 根据您的具体需要在Rcpp中编写一个函数。在这里,2个嵌套for循环可以解决这个问题。然而,你无法重新编码你需要的一切。
  • big.matrix的列块上使用R函数并汇总结果。它很容易做,只使用R代码。

在您的情况下,列数增加10,000倍:

big.matrix

因此,require(bigmemory) x <- as.big.matrix( matrix( sample(1:10, 20000, replace=TRUE), 5, 40000, dimnames=list( NULL, rep(c("a", "b", "c", "d"), 10000) ) ) ) print(system.time( true <- sqrt(colSums(x[,]^2)) )) print(system.time( test1 <- biganalytics::apply(x, 2, function(x) {sqrt(sum(x^2))}) )) print(all.equal(test1, true)) 非常快,但需要RAM中的所有矩阵,而colSums速度慢但内存效率高。折衷方案是使用这样的东西:

biganalytics::apply

修改:现在在 bigstatsr 包中实现:

CutBySize <- function(m, block.size, nb = ceiling(m / block.size)) {
  int <- m / nb

  upper <- round(1:nb * int)
  lower <- c(1, upper[-nb] + 1)
  size <- c(upper[1], diff(upper))

  cbind(lower, upper, size)
}

seq2 <- function(lims) seq(lims["lower"], lims["upper"])

require(foreach)
big_aggregate <- function(X, FUN, .combine, block.size = 1e3) {
  intervals <- CutBySize(ncol(X), block.size)

  foreach(k = 1:nrow(intervals), .combine = .combine) %do% {
    FUN(X[, seq2(intervals[k, ])])
  }
}

print(system.time(
  test2 <- big_aggregate(x, function(X) sqrt(colSums(X^2)), .combine = 'c')
))
print(all.equal(test2, true))

答案 1 :(得分:0)

我不知道这是否是最快的方法,尝试使用:

biganalytics::apply(x, 2, function(x) {sqrt(sum(x^2))})