r - 在 R 中,将一个向量随机分成 k 个块?
问题描述
我在这里看到了关于“将向量 X 拆分为 R 中的 Y 块”问题的许多变体。例如:这里和这里只有两个。所以,当我意识到我需要将一个向量分成 Y个随机大小的块时,我惊讶地发现随机性要求可能是“新的”——我在这里找不到这样做的方法。
所以,这是我制定的:
k.chunks = function(seq.size, n.chunks) {
break.pts = sample(1:seq.size, n.chunks, replace=F) %>% sort() #Get a set of break points chosen from along the length of the vector without replacement so no duplicate selections.
groups = rep(NA, seq.size) #Set up the empty output vector.
groups[1:break.pts[1]] = 1 #Set the first set of group affiliations because it has a unique start point of 1.
for (i in 2:(n.chunks)) { #For all other chunks...
groups[break.pts[i-1]:break.pts[i]] = i #Set the respective group affiliations
}
groups[break.pts[n.chunks]:seq.size] = n.chunks #Set the last group affiliation because it has a unique endpoint of seq.size.
return(groups)
}
我的问题是:这在某种程度上是不优雅或低效的吗?它会在我计划做的代码中被调用 1000 次,所以效率对我来说很重要。for
避免循环或必须“手动”设置第一组和最后一组会特别好。我的另一个问题:是否有逻辑输入可以打破这一点?我承认n.chunks
不能 > seq.size
,所以我的意思是除此之外。
解决方案
对于较小的数字,这应该很快。但这里有一种更简洁的方式。
k.chunks2 = function(seq.size, n.chunks) {
break.pts <- sort(sample(1:seq.size, n.chunks - 1, replace = FALSE))
break.len <- diff(c(0, break.pts, seq.size))
groups <- rep(1:n.chunks, times = break.len)
return(groups)
}
如果你真的得到了大量的组,我认为这sort
将开始花费你的执行时间。所以你可以做这样的事情(可能可以调整得更快)根据比例进行分割。我不确定我对此有何感受,因为随着n.chunks
变得非常大,比例会变得非常小。但它更快。
k.chunks3 = function(seq.size, n.chunks) {
props <- runif(n.chunks)
grp.props <- props / sum(props)
chunk.size <- floor(grp.props[-n.chunks] * seq.size)
break.len <- c(chunk.size, seq.size - sum(chunk.size))
groups <- rep(1:n.chunks, times = break.len)
return(groups)
}
运行基准测试,我认为其中任何一个都足够快(单位是微秒)。
n <- 1000
y <- 10
microbenchmark::microbenchmark(k.chunks(n, y),
k.chunks2(n, y),
k.chunks3(n, y))
Unit: microseconds
expr min lq mean median uq max neval
k.chunks(n, y) 49.9 52.05 59.613 53.45 58.35 251.7 100
k.chunks2(n, y) 46.1 47.75 51.617 49.25 52.55 107.1 100
k.chunks3(n, y) 8.1 9.35 11.412 10.80 11.75 44.2 100
但是随着数字变大,你会注意到一个有意义的加速(注意现在的单位是毫秒)。
n <- 1000000
y <- 100000
microbenchmark::microbenchmark(k.chunks(n, y),
k.chunks2(n, y),
k.chunks3(n, y))
Unit: milliseconds
expr min lq mean median uq max neval
k.chunks(n, y) 46.9910 51.38385 57.83917 54.54310 56.59285 113.5038 100
k.chunks2(n, y) 17.2184 19.45505 22.72060 20.74595 22.73510 69.5639 100
k.chunks3(n, y) 7.7354 8.62715 10.32754 9.07045 10.44675 58.2093 100
总而言之,我可能会使用我的k.chunks2()
功能。
推荐阅读
- c++ - C++中的二分查找算法
- android - 在反应原生屏幕后显示插页式广告
- java - 无法运行 Struts 2 Hello World
- python - 安装 jupyter notebook 出现内核错误,如何解决?
- sql - 我正在尝试将 Oracle 视图转换为 SQL,但查询性能存在问题
- python-3.x - 如何使用 Numba 正确加速?
- javascript - Jquery if value <= something don't working
- javascript - 如何一次自动填充输入类型 1 的字母?
- python - 衰减数的python矩阵
- node.js - 正文解析器:无法从表单中获取值