英文:
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 <- 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))]
)
答案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 <- 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 <- 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 <- 100
v <- as.vector(t(volume))
s <- (1:n) * n - sample(1:n, n, replace = T) + 1
v展开收缩
Test case
Using a smaller matrix with easy to follow numbers
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
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.int
和cbind
,如下所示:
> 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
> 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论