本文介绍了如何对稀疏矩阵进行排序并存储结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个很大的稀疏矩阵:
> str(qtr_sim)
Formal class 'dsCMatrix' [package "Matrix"] with 7 slots
..@ i : int [1:32395981] 0 1 2 3 4 5 6 7 8 1 ...
..@ p : int [1:28182] 0 1 2 3 4 5 6 7 8 9 ...
..@ Dim : int [1:2] 28181 28181
..@ Dimnames:List of 2
.. ..$ : chr [1:28181] "1000191" "1000404" "1000457" "1000541" ...
.. ..$ : chr [1:28181] "1000191" "1000404" "1000457" "1000541" ...
..@ x : num [1:32395981] 1 1 1 1 1 ...
..@ uplo : chr "U"
..@ factors : list()
该矩阵包含余弦相似值--介于0和1之间的数字。
这样一个矩阵的例子,其中A,...,E I将调用"Products":
>A
5 x 5 sparse Matrix of class "dgCMatrix"
A B C D E
A 1.00 0.51 . . 0.03
B 0.51 1.00 0.40 . 0.06
C . 0.40 1.00 0.1 0.05
D . . 0.10 1.0 .
E 0.03 0.06 0.05 . 1.00
> dput(A)
new("dgCMatrix"
, i = c(0L, 1L, 4L, 0L, 1L, 2L, 4L, 1L, 2L, 3L, 4L, 2L, 3L, 0L, 1L,
2L, 4L)
, p = c(0L, 3L, 7L, 11L, 13L, 17L)
, Dim = c(5L, 5L)
, Dimnames = list(c("A", "B", "C", "D", "E"), c("A", "B", "C", "D", "E"))
, x = c(1, 0.51, 0.03, 0.51, 1, 0.4, 0.06, 0.4, 1, 0.1, 0.05, 0.1,
1, 0.03, 0.06, 0.05, 1)
, factors = list()
)
我需要找到一种从矩阵A获得两个矩阵B、C的快速方法:
>B
5 x 5 sparse Matrix of class "dgCMatrix"
A B C D E
[1,] 1.00 1.00 1.00 1.0 1.00
[2,] 0.51 0.51 0.40 0.1 0.06
[3,] 0.03 0.40 0.10 . 0.05
[4,] . 0.06 0.05 . 0.03
[5,] . . . . .
>C
A B C D E
[1,] A B C D E
[2,] B A B C B
[3,] E C D NA C
[4,] NA E E NA A
[5,] NA NA NA NA NA
不一定要有"na",但我在代码中使用了它(见下文)。
我正在使用此方法:
B <- C <- matrix(NA, nrow = nrow(A), ncol = ncol(A))
colnames(C) <- colnames(B) <- colnames(A)
for (j in 1:nrow(A)){
c <- A[ ,2, drop = F]
posi <- colnames(c)
d <- order(c, decreasing = T)
mat <- c[d, ]
if (which(names(mat) == posi) != 1){
firstr <- mat[which(names(mat) == posi)]
mat <- mat[-which(names(mat) == posi)]
mat <- c(firstr,mat)
} #this is because sometimes similarity of value 1 doesn't
#only belong to one products and I need first row = column
#names !!!! The next product with similarity 1 should be
#in next row and so on.
myNAs <- lapply(mat, function(x) which(x == 0))
a <- as.numeric(which(myNAs == 1))
names(mat)[a] <- NA
C[,j] <- names(mat)
B[,j] <- as.numeric(mat)
}
但这种方法非常慢。请注意,原始稀疏矩阵比本例A大得多。
我如何改进我的方法?
推荐答案
好的,也许这是有用的:
library(data.table)
DT <- data.table(val = A@x, i = A@i + 1L,
product = rownames(A)[A@i + 1L],
j = rep(rownames(A), diff(A@p)))
setorderv(DT, c("j", "val"), c(1L, -1L))
DT[, newi := seq_len(.N), by = j]
dcast(DT, newi ~ j, value.var = "val")
# newi A B C D E
#1: 1 1.00 1.00 1.00 1.0 1.00
#2: 2 0.51 0.51 0.40 0.1 0.06
#3: 3 0.03 0.40 0.10 NA 0.05
#4: 4 NA 0.06 0.05 NA 0.03
dcast(DT, newi ~ j, value.var = "product")
# newi A B C D E
#1: 1 A B C D E
#2: 2 B A B C B
#3: 3 E C D NA C
#4: 4 NA E E NA A
当然,重塑可能会创建大而密集的对象,从而耗尽您的内存。如果这是一个问题,您将需要反转第一步,并尝试使用newi
、j
和val
创建稀疏矩阵。 这篇关于如何对稀疏矩阵进行排序并存储结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!