首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用向量构造二进制矩阵的简洁方法

用向量构造二进制矩阵的简洁方法
EN

Stack Overflow用户
提问于 2014-08-12 18:17:33
回答 2查看 1.1K关注 0票数 1

我有一个有趣的挑战:我试图从一个整数向量构造一个二进制矩阵。二进制矩阵应该包含与向量长度相同的行数,以及整数向量中的最大值列。矩阵中的ith行将对应于向量的ith元素,其中在j位置包含1的行,其中j等于向量的ith元素的值;否则,该行包含零。如果ith整数的值为0,则整个ith行应为0。

为了使这一切变得更简单,下面是一个可重复工作的示例:

代码语言:javascript
运行
复制
set.seed(1)
playv<-sample(0:5,20,replace=TRUE)#sample integer vector

playmat<-matrix(playv,nrow=length(playv),ncol=max(playv))#create matrix from vector

for (i in 1:length(playv)){
pos<-as.integer(playmat[i,1])
playmat[i,pos]<-1
playmat[i,-pos]<-0}

    head(playmat)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    0    1    0    0    0
[3,]    0    0    1    0    0
[4,]    0    0    0    0    1
[5,]    1    0    0    0    0
[6,]    0    0    0    0    1

上面的解决方案是正确的,我只是想让一些更健壮的东西。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-12 18:34:51

代码语言:javascript
运行
复制
set.seed(1)
playv <- sample(0:5,20,replace=TRUE)
playv <- as.character(playv)
results <- model.matrix(~playv-1)

您可以重命名result中的列。

我喜欢Ananda提供的解决方案,并将其与model.matrix进行了比较。这是一个密码

代码语言:javascript
运行
复制
library(microbenchmark)

set.seed(1)
v <- sample(1:10,1e6,replace=TRUE)

f1 <- function(vec) {
  vec <- as.character(vec)
  model.matrix(~vec-1)
}

f2 <- function(vec) {
  table(sequence(length(vec)), vec)
}

microbenchmark(f1(v), f2(v), times=10)

model.matrixtable快一点

代码语言:javascript
运行
复制
Unit: seconds
  expr      min       lq   median       uq      max neval
 f1(v) 2.890084 3.147535 3.296186 3.377536 3.667843    10
 f2(v) 4.824832 5.625541 5.757534 5.918329 5.966332    10
票数 4
EN

Stack Overflow用户

发布于 2014-08-13 05:37:48

当然,你也可以使用table

代码语言:javascript
运行
复制
> table(sequence(length(playv)), playv)
    playv
     0 1 2 3 4 5
  1  0 1 0 0 0 0
  2  0 0 1 0 0 0
  3  0 0 0 1 0 0
  4  0 0 0 0 0 1
  5  0 1 0 0 0 0
  6  0 0 0 0 0 1
  7  0 0 0 0 0 1
  8  0 0 0 1 0 0
  9  0 0 0 1 0 0
  10 1 0 0 0 0 0
  11 0 1 0 0 0 0
  12 0 1 0 0 0 0
  13 0 0 0 0 1 0
  14 0 0 1 0 0 0
  15 0 0 0 0 1 0
  16 0 0 1 0 0 0
  17 0 0 0 0 1 0
  18 0 0 0 0 0 1
  19 0 0 1 0 0 0
  20 0 0 0 0 1 0

如果速度是个问题的话,我建议采用手动的方法。首先,确定向量中的唯一值。第二,创建一个空矩阵来填充。第三,使用矩阵索引来确定应填写为1的职位。

如下所示:

代码语言:javascript
运行
复制
f3 <- function(vec) {
  U <- sort(unique(vec))
  M <- matrix(0, nrow = length(vec), 
              ncol = length(U), 
              dimnames = list(NULL, U))
  M[cbind(seq_len(length(vec)), match(vec, U))] <- 1L
  M
}

使用将是f3(playv)

在基准中加上这一点,我们得到:

代码语言:javascript
运行
复制
library(microbenchmark)
microbenchmark(f1(v), f2(v), f3(v), times = 10)
# Unit: milliseconds
#   expr       min        lq    median        uq       max neval
#  f1(v) 2104.4808 3151.4308 3314.8173 3344.6696 4023.5246    10
#  f2(v) 3956.5678 4782.7863 5994.4448 6320.1901 6646.0405    10
#  f3(v)  486.4406  574.1133  746.9112  927.3407  987.9121    10
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25271353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档