我想将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] 删除。
我来说两句