首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从矩阵的每行中随机采样

从矩阵的每行中随机采样
EN

Stack Overflow用户
提问于 2019-02-19 09:23:58
回答 3查看 66关注 0票数 1

给定一个5x5矩阵:

代码语言:javascript
复制
dataset=matrix(cbind(c(1,1,2,2,0),
                     c(1,1,2,0,0),
                     c(0,0,0,1,0),
                     c(0,0,1,1,1),
                     c(1,2,3,4,0))
dataset
      [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    0    0    1
[2,]    1    1    0    0    2
[3,]    2    2    0    1    3
[4,]    2    0    1    1    4
[5,]    0    0    0    1    0

我想要从矩阵的每一行中采样1个观测值,该行的采样值等于1,并且我想创建一个新矩阵,其中随机采样值在新矩阵中设置为True,所有其他值设置为false。下面提供了预期输出的示例:

代码语言:javascript
复制
       1     2     3     4     5  
1   FALSE  TRUE FALSE FALSE FALSE 
2    TRUE FALSE FALSE FALSE FALSE
3   FALSE FALSE FALSE  TRUE FALSE 
4   FALSE FALSE  TRUE FALSE FALSE 
5   FALSE FALSE FALSE  TRUE FALSE 

有没有人能帮我弄清楚怎么才能做到这点。

EN

回答 3

Stack Overflow用户

发布于 2019-02-19 09:35:52

这里有一个选项

代码语言:javascript
复制
# Courtesy of Hadley (avoids the "surprise" sample result when we have only one element)
# [http://r.789695.n4.nabble.com/using-quot-sample-quot-for-a-vector-of-length-1-td2299330.html]
resample <- function(x, ...) x[sample.int(length(x), ...)]

set.seed(2019)
t(apply(dataset, 1, function(x) 
    replace(rep(FALSE, length(x)), resample(which(x == 1), 1), TRUE)))
#      [,1]  [,2]  [,3]  [,4]  [,5]
#[1,] FALSE FALSE FALSE FALSE  TRUE
#[2,] FALSE  TRUE FALSE FALSE FALSE
#[3,] FALSE FALSE FALSE  TRUE FALSE
#[4,] FALSE FALSE FALSE  TRUE FALSE
#[5,] FALSE FALSE FALSE  TRUE FALSE

为了重复性,我添加了一个固定的随机种子;从dataset的每一行中删除以随机抽样1

样本数据

代码语言:javascript
复制
dataset=matrix(
    c(1,1,2,2,0,1,1,2,0,0,0,0,0,1,0,0,0,1,1,1,1,2,3,4,0),
    nrow = 5, ncol = 5)
dataset
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    1    1    0    0    1
#[2,]    1    1    0    0    2
#[3,]    2    2    0    1    3
#[4,]    2    0    1    1    4
#[5,]    0    0    0    1    0
票数 2
EN

Stack Overflow用户

发布于 2019-02-19 09:41:42

如果我理解这个请求,那么这应该是一个有效的答案:

代码语言:javascript
复制
(dataset==1) * rbinom(length(dataset), 1, 0.5)

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    1
[2,]    0    1    0    0    0
[3,]    0    0    0    1    0
[4,]    0    0    0    1    0
[5,]    0    0    0    1    0

我的理解是,您只需要在与原始矩阵中的1相同的位置上为真(或等价于1),但只有一些随机样本为真(或1)。

票数 1
EN

Stack Overflow用户

发布于 2019-02-19 10:18:37

我的方法是创建一个等于1的所有单元格的大列表,然后每行只采样一个单元格,并更新矩阵的副本。如下所示:

代码语言:javascript
复制
idx <- which(dataset==1, arr.ind=TRUE)
idx <- idx[sample(nrow(idx)),]
idx <- idx[!duplicated(idx[,"row"]),]
mat <- matrix(FALSE, nrow=nrow(dataset), ncol=ncol(dataset))
mat[idx] <- TRUE

mat
#      [,1]  [,2]  [,3]  [,4]  [,5]
#[1,] FALSE  TRUE FALSE FALSE FALSE
#[2,]  TRUE FALSE FALSE FALSE FALSE
#[3,] FALSE FALSE FALSE  TRUE FALSE
#[4,] FALSE FALSE  TRUE FALSE FALSE
#[5,] FALSE FALSE FALSE  TRUE FALSE

这也会有很好的伸缩性。下面是在大约2.5秒内处理的500万行数据:

代码语言:javascript
复制
dataset <- dataset[rep(1:5,1e6),]
system.time({
idx <- which(dataset==1, arr.ind=TRUE)
idx <- idx[sample(nrow(idx)),]
idx <- idx[!duplicated(idx[,"row"]),]
mat <- matrix(FALSE, nrow=nrow(dataset), ncol=ncol(dataset))
mat[idx] <- TRUE
})
#   user  system elapsed 
#   2.32    0.22    2.58 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54757602

复制
相关文章

相似问题

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