从矩阵的每一行中随机抽取一个元素。

huangapple go评论78阅读模式
英文:

R: sample random element from each row of a matrix

问题

以下是已翻译的内容:

"Can anybody help me to optimize my way of sampling random values for each row of a matrix?

Thus far I have two ways of doing it:

volume <- matrix(rnorm(10000), 100, 100)
microbenchmark(
test <- apply(volume, 1, function(x) {sample(x, 1)}),

make matrix into a vector, sample one time for all rows at the same time,

and then add 0, 100, 200 ... to each sample

test2 <- c(t(volume))[sample(x=1:ncol(volume), size=nrow(volume), replace=T) + seq(from=0, by=ncol(volume), length.out=nrow(volume))]
)"

英文:

Can anybody help me to optimize my way of sampling random values for each row of a matrix?

Thus far I have two ways of doing it:

volume &lt;- matrix(rnorm(10000), 100, 100)
microbenchmark(
  
  test &lt;- apply(volume, 1, function(x) {sample(x, 1)}),
  # make matrix into a vector, sample one time for all rows at the same time,
  # and then add 0, 100, 200 ...  to each sample
  test2 &lt;- c(t(volume))[sample(x=1:ncol(volume), size=nrow(volume), replace=T) + seq(from=0, by=ncol(volume), length.out=nrow(volume))] 
)

答案1

得分: 4

你可以使用一个包含两列的矩阵来索引一个矩阵,其中第一列是行的选择器,第二列是列的选择器。

例如:

index <- matrix(c(1, 4, 1, 3), ncol = 2)
index
     [,1] [,2]
[1,]    1    1
[2,]    4    3
matrix(c(1:15), ncol = 3)
     [,1] [,2] [,3]
[1,]    1    6   11
[2,]    2    7   12
[3,]    3    8   13
[4,]    4    9   14
[5,]    5   10   15
matrix(c(1:15), ncol = 3)[index]
[1]  1 14

应用相同的原理,我们可以创建一个索引矩阵,其中第一列为每行的序号(1:100),第二列包含来自1到100的随机整数,用于选择随机列。

test3 <- volume[matrix(c(1:100, sample.int(100, 100, replace = TRUE)), nrow = 100)]

这似乎会更快一些,可能是因为R中的向量化,但我不足够强大,无法确定。希望这对你有帮助或给你其他想法!

英文:

You can index a matrix with a 2 column matrix so that the first column is the selector of the row and the second one is the selector for column.

For example:

index &lt;- matrix(c(1, 4, 1, 3), ncol = 2)
index
     [,1] [,2]
[1,]    1    1
[2,]    4    3
matrix(c(1:15), ncol = 3)
     [,1] [,2] [,3]
[1,]    1    6   11
[2,]    2    7   12
[3,]    3    8   13
[4,]    4    9   14
[5,]    5   10   15
matrix(c(1:15), ncol = 3)[index]
[1]  1 14

Applying the same principle we can create a matrix of indexes with first column for each row (1:100) and second column with a random integer from 1 to 100 to select a random column.

test3 &lt;- volume[matrix(c(1:100, sample.int(100, 100, replace = TRUE)), nrow = 100)]

It seems to be a little faster, probably because of vectorisation in R but I'm not strong enough to tell. I hope this helped you or gave you others ideas!

答案2

得分: 2

另一种方法:

n <- 100
v <- as.vector(t(volume))
s <- (1:n) * n - sample(1:n, n, replace = T) + 1
v
展开收缩

测试案例

使用较小的矩阵和易于跟踪的数字

n <- 10

volume <- matrix(1:(n*n), n, n)

v <- as.vector(t(volume))
s <- (1:n) * n - sample(1:n, n, replace = T) + 1
v
展开收缩
[1] 41 12 53 4 15 26 47 88 89 80

我们可以轻松逐行交叉检查,确保我们有一个来自随机列的值。

我在这里使用了 rbenchmark

   test replications elapsed relative user.self sys.self user.child sys.child
1 test1        10000   10.39    8.731      9.80     0.50         NA        NA
2 test2        10000    1.53    1.286      0.98     0.53         NA        NA
3 v
展开收缩
10000 1.19 1.000 0.84 0.34 NA NA
英文:

Another approach:

n &lt;- 100
v &lt;- as.vector(t(volume))
s &lt;- (1:n) * n - sample(1:n, n, replace = T) + 1
v
展开收缩

Test case

Using a smaller matrix with easy to follow numbers

n &lt;- 10

volume &lt;- matrix(1:(n*n), n, n)

v &lt;- as.vector(t(volume))
s &lt;- (1:n) * n -  sample(1:n, n, replace = T) + 1
v
展开收缩
[1] 41 12 53 4 15 26 47 88 89 80

We can easily cross check row by row that we have one value from a random column.

I used rbenchmark here

   test replications elapsed relative user.self sys.self user.child sys.child
1 test1        10000   10.39    8.731      9.80     0.50         NA        NA
2 test2        10000    1.53    1.286      0.98     0.53         NA        NA
3 v
展开收缩
10000 1.19 1.000 0.84 0.34 NA NA

答案3

得分: 1

您可以尝试使用sample.intcbind,如下所示:

> volume[cbind(sample.int(nrow(volume)), seq(ncol(volume)))] + 100 * (seq(nrow(volume)) - 1)
  [1]   -1.224613   98.512540  200.945185  301.154825  398.633888  500.537326
  [7]  599.296667  699.875739  801.979633  901.943536 1000.485389 1101.245489
 [13] 1199.927407 1300.614396 1401.376295 1499.845985 1600.325472 1700.827938
 [19] 1800.848768 1898.982145 1999.513529 2099.892262 2200.420631 2300.353487
 [25] 2400.006175 2499.805057 2601.976288 2698.841332 2801.744629 2900.781041
 [31] 3001.973210 3100.717182 3202.547228 3299.413149 3400.251934 3500.411278
 [37] 3600.147031 3700.617010 3799.195733 3899.599753 3999.305972 4100.592828
 [43] 4199.306696 4298.941681 4400.608532 4500.866239 4601.324509 4698.683332
 [49] 4800.558514 4898.423218 4998.912282 5099.734288 5200.426110 5299.556283
 [55] 5398.069062 5499.971494 5599.574838 5701.268051 5799.335310 5899.293448
 [61] 5999.440561 6100.137712 6200.173128 6300.441285 6399.531312 6499.438840
 [67] 6600.213682 6700.742909 6801.688150 6900.652646 7001.198283 7099.355430
 [73] 7198.598821 7297.607903 7400.581176 7501.050185 7601.602181 7698.798794
 [79] 7796.995970 7898.064790 7999.908998 8102.625282 8198.114373 8300.538023
 [85] 8398.521912 8500.918616 8599.469763 8699.102379 8798.473842 8899.133405
 [91] 9000.673422 9100.615656 9199.422079 9300.055959 9400.128205 9499.914517
 [97] 9600.943887 9698.741291 9799.654779 9900.996018

这是代码的翻译部分。

英文:

You can try sample.int with cbind like below

&gt; volume[cbind(sample.int(nrow(volume)), seq(ncol(volume)))] + 100 * (seq(nrow(volume)) - 1)
  [1]   -1.224613   98.512540  200.945185  301.154825  398.633888  500.537326
  [7]  599.296667  699.875739  801.979633  901.943536 1000.485389 1101.245489
 [13] 1199.927407 1300.614396 1401.376295 1499.845985 1600.325472 1700.827938
 [19] 1800.848768 1898.982145 1999.513529 2099.892262 2200.420631 2300.353487
 [25] 2400.006175 2499.805057 2601.976288 2698.841332 2801.744629 2900.781041
 [31] 3001.973210 3100.717182 3202.547228 3299.413149 3400.251934 3500.411278
 [37] 3600.147031 3700.617010 3799.195733 3899.599753 3999.305972 4100.592828
 [43] 4199.306696 4298.941681 4400.608532 4500.866239 4601.324509 4698.683332
 [49] 4800.558514 4898.423218 4998.912282 5099.734288 5200.426110 5299.556283
 [55] 5398.069062 5499.971494 5599.574838 5701.268051 5799.335310 5899.293448
 [61] 5999.440561 6100.137712 6200.173128 6300.441285 6399.531312 6499.438840
 [67] 6600.213682 6700.742909 6801.688150 6900.652646 7001.198283 7099.355430
 [73] 7198.598821 7297.607903 7400.581176 7501.050185 7601.602181 7698.798794
 [79] 7796.995970 7898.064790 7999.908998 8102.625282 8198.114373 8300.538023
 [85] 8398.521912 8500.918616 8599.469763 8699.102379 8798.473842 8899.133405
 [91] 9000.673422 9100.615656 9199.422079 9300.055959 9400.128205 9499.914517
 [97] 9600.943887 9698.741291 9799.654779 9900.996018

huangapple
  • 本文由 发表于 2023年3月9日 22:23:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75685873.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定