将R中的稀疏矩阵的对角线归零的内存有效方法

戴泽尔

我想将R中的稀疏矩阵的对角线清零。我的蛮力方式是将其显式设置为零,但这似乎效率很低。有没有更有效的方法?

require(Matrix)
A <- as(rsparsematrix(nrow = 1e7, ncol = 1e7, nnz = 1e4), "sparseMatrix")
diag(A) <- 0
A <- drop0(A)  # cleaning up

澄清度和分辨率:我最初担心的是Matrix将对角线上的实际零填充为稀疏矩阵。事实并非如此(最后,尽管在此期间,请参见下面的评论)。要看到这一点,请考虑如果将对角线设置为一个会发生什么:

A <- as(rsparsematrix(nrow = 1e7, ncol = 1e7, nnz = 1e4), "sparseMatrix")
format(object.size(A), units = "Mb")

[1]“ 38.3 Mb”

diag(A) <- 1
format(object.size(A), units = "Mb")

[1]“ 152.7 Mb”

我们添加的许多非零元素会耗尽O(n)内存,其中n是矩阵的暗淡。但是,随着diag(A) <- 0我们得到:

diag(A) <- 1
format(object.size(A), units = "Mb")

[1]“ 38.3 Mb”

即,Matrix已经有效地处理了这种情况。

用户名

您可以很快找到非零条目:

ij <- which(A != 0, arr.ind = TRUE)

# Subset to those on the diagonal:

ij <- ij[ij[,1] == ij[,2],,drop = FALSE]

# And set those entries to zero:

A[ij] <- 0

编辑添加:

正如对原始问题的修订所言,这最终并不会节省太多内存,但是速度要快得多。diag(A) <- 0语句在我的计算机上大约需要3.2秒,而这3个步骤大约需要0.2秒。计时方法如下:

library(microbenchmark)
microbenchmark(A <- as(rsparsematrix(nrow = 1e7, ncol = 1e7, nnz = 1e4), "sparseMatrix"),
{A <- as(rsparsematrix(nrow = 1e7, ncol = 1e7, nnz = 1e4), "sparseMatrix"); diag(A) <- 0},
{A <- as(rsparsematrix(nrow = 1e7, ncol = 1e7, nnz = 1e4), "sparseMatrix");ij <- which(A != 0, arr.ind = TRUE);ij <- ij[ij[,1] == ij[,2],,drop = FALSE];A[ij] <- 0}, times = 10)

当我运行它时,我看到矩阵创建的中间时间为137毫秒,没有别的,创建时间为3351毫秒,加上diag(A)调用,创建时间为319毫秒,其后是我的代码。

它还可以在中间步骤中节省大量内存,这可以使用内存配置文件查看:Rprof(memory=TRUE); run code ; Rprof(NULL); summaryRprof()

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章