如何高效实现从1:35中多次抽取排序后的k大小随机样本?
更快的批量抽取排序样本实现方式
原代码使用replicate循环百万次调用sample和sort,每次函数调用的开销累积导致速度缓慢,以下是几种更高效的实现方案:
方案1:预生成所有组合后随机抽样(推荐k较小时使用)
当从35个元素中抽取5个时,所有可能的无放回组合仅324632种,远小于100万次抽样需求。我们可以先一次性生成所有组合,再通过有放回抽样得到结果,完全避免循环操作,速度提升最为明显。
# 生成35选5的所有组合 all_combinations <- combn(1:35, 5) # 随机抽取100万个组合(允许重复) sample_indices <- sample(ncol(all_combinations), 1000000, replace = TRUE) # 获取最终结果(5行100万列的矩阵,每列对应一个排序后的样本) result <- all_combinations[, sample_indices]
方案2:用批量行排序替代逐行sort调用
若k较大导致预生成组合内存不足,可借助matrixStats包的rowSort函数(C语言实现的批量行排序),减少循环中的sort调用开销:
library(matrixStats) n <- 1000000 k <- 5 # 生成样本矩阵(每列对应一个未排序的无放回样本) sample_matrix <- vapply(1:n, function(x) sample(1:35, k), integer(k)) # 转置后按行排序,再转置回原结构 result <- t(rowSort(t(sample_matrix)))
方案3:优化循环调用(无需额外包)
如果不想加载第三方包,用lapply配合do.call生成矩阵的方式,比原生replicate略高效:
n <- 1000000 k <- 5 # 生成所有排序后的样本列表,再合并为矩阵 sample_list <- lapply(1:n, function(x) sort(sample(1:35, k))) result <- do.call(cbind, sample_list)
内容的提问来源于stack exchange,提问作者Mohan
相关产品推荐
相关产品推荐

