如何从列索引向量中向量化扩展压缩稀疏矩阵?
How to vectorize expanding a compressed sparse matrix from vector of column indices?
我想从向量构建一个矩阵如下:如果y的第一个元素是5,我想使矩阵的第一行和第5列为1。行中的其他元素为0。
y=round(runif(30)*9)+1
y_m=matrix(rep(0,length(y)*10),ncol=10)
for (i in 1:length(y)){
y_m[i,y[i]]=1;
}
有什么办法可以避免for循环吗?我试图做 y_m[,y]=1
但显然它不起作用。
您可以使用:
y_m[cbind(1:length(y), y)] <- 1
由于您有一个稀疏矩阵,您可能需要:
sparse_y_m <- Matrix::sparseMatrix(i = 1:length(y), j = y, x = 1)
如果你想要一个完整的矩阵,使用
y_m <- as.matrix(sparse_y_m)
是:使用两列索引矩阵。来自 ?"["
:
When indexing arrays by ‘[’ a single argument ‘i’ can be a
matrix with as many columns as there are dimensions of ‘x’;
the result is then a vector with elements corresponding to
the sets of indices in each row of ‘i’.
设置:
set.seed(101)
y <- round(runif(30)*9)+1
你的方式(我稍微简化了矩阵构造):
y_m <- matrix(0,ncol=10,nrow=length(y))
for (i in 1:length(y)){
y_m[i,y[i]] <- 1
}
通过矩阵索引:
y_m2 <- matrix(0,ncol=10,nrow=length(y))
y_m2[cbind(1:length(y),y)] <- 1
检查:
all.equal(y_m,y_m2) ## TRUE
您可以使用 xtabs
仅从 y
生成矩阵,通过行号索引传播 1 的向量,即 seq_along(y)
然后 y
本身:
xtabs(rep(1, length(y)) ~ seq_along(y) + y)
## y
## seq_along(y) 1 2 3 4 5 6 7 8 9 10
## 1 0 0 0 1 0 0 0 0 0 0
## 2 0 1 0 0 0 0 0 0 0 0
## 3 1 0 0 0 0 0 0 0 0 0
## 4 0 0 0 0 0 0 1 0 0 0
## 5 0 0 0 1 0 0 0 0 0 0
## 6 0 0 0 1 0 0 0 0 0 0
## ...
或将其设为稀疏矩阵:
xtabs(rep(1, length(y)) ~ seq_along(y) + y, sparse = TRUE)
## 30 x 10 sparse Matrix of class "dgCMatrix"
##
## 1 . . . 1 . . . . . .
## 2 . 1 . . . . . . . .
## 3 1 . . . . . . . . .
## 4 . . . . . . 1 . . .
## 5 . . . 1 . . . . . .
## 6 . . . 1 . . . . . .
## ...
或使用 data.frame 设置以获得更好的标签:
xtabs(i ~ row + y, data.frame(y, i = 1, row = seq_along(y)))
## y
## row 1 2 3 4 5 6 7 8 9 10
## 1 0 0 0 1 0 0 0 0 0 0
## 2 0 1 0 0 0 0 0 0 0 0
## 3 1 0 0 0 0 0 0 0 0 0
## 4 0 0 0 0 0 0 1 0 0 0
## 5 0 0 0 1 0 0 0 0 0 0
## 6 0 0 0 1 0 0 0 0 0 0
## ...
我想从向量构建一个矩阵如下:如果y的第一个元素是5,我想使矩阵的第一行和第5列为1。行中的其他元素为0。
y=round(runif(30)*9)+1
y_m=matrix(rep(0,length(y)*10),ncol=10)
for (i in 1:length(y)){
y_m[i,y[i]]=1;
}
有什么办法可以避免for循环吗?我试图做 y_m[,y]=1
但显然它不起作用。
您可以使用:
y_m[cbind(1:length(y), y)] <- 1
由于您有一个稀疏矩阵,您可能需要:
sparse_y_m <- Matrix::sparseMatrix(i = 1:length(y), j = y, x = 1)
如果你想要一个完整的矩阵,使用
y_m <- as.matrix(sparse_y_m)
是:使用两列索引矩阵。来自 ?"["
:
When indexing arrays by ‘[’ a single argument ‘i’ can be a matrix with as many columns as there are dimensions of ‘x’; the result is then a vector with elements corresponding to the sets of indices in each row of ‘i’.
设置:
set.seed(101)
y <- round(runif(30)*9)+1
你的方式(我稍微简化了矩阵构造):
y_m <- matrix(0,ncol=10,nrow=length(y))
for (i in 1:length(y)){
y_m[i,y[i]] <- 1
}
通过矩阵索引:
y_m2 <- matrix(0,ncol=10,nrow=length(y))
y_m2[cbind(1:length(y),y)] <- 1
检查:
all.equal(y_m,y_m2) ## TRUE
您可以使用 xtabs
仅从 y
生成矩阵,通过行号索引传播 1 的向量,即 seq_along(y)
然后 y
本身:
xtabs(rep(1, length(y)) ~ seq_along(y) + y)
## y
## seq_along(y) 1 2 3 4 5 6 7 8 9 10
## 1 0 0 0 1 0 0 0 0 0 0
## 2 0 1 0 0 0 0 0 0 0 0
## 3 1 0 0 0 0 0 0 0 0 0
## 4 0 0 0 0 0 0 1 0 0 0
## 5 0 0 0 1 0 0 0 0 0 0
## 6 0 0 0 1 0 0 0 0 0 0
## ...
或将其设为稀疏矩阵:
xtabs(rep(1, length(y)) ~ seq_along(y) + y, sparse = TRUE)
## 30 x 10 sparse Matrix of class "dgCMatrix"
##
## 1 . . . 1 . . . . . .
## 2 . 1 . . . . . . . .
## 3 1 . . . . . . . . .
## 4 . . . . . . 1 . . .
## 5 . . . 1 . . . . . .
## 6 . . . 1 . . . . . .
## ...
或使用 data.frame 设置以获得更好的标签:
xtabs(i ~ row + y, data.frame(y, i = 1, row = seq_along(y)))
## y
## row 1 2 3 4 5 6 7 8 9 10
## 1 0 0 0 1 0 0 0 0 0 0
## 2 0 1 0 0 0 0 0 0 0 0
## 3 1 0 0 0 0 0 0 0 0 0
## 4 0 0 0 0 0 0 1 0 0 0
## 5 0 0 0 1 0 0 0 0 0 0
## 6 0 0 0 1 0 0 0 0 0 0
## ...