我有一个序列
val input = Seq(1,3,4,5,9,11...)
我想随机选择它的一个子集。最快的方法是什么。
我目前是这样实现的:
//ratio是子组占全组的百分比
def randomSelect(ratio:Double): Boolean = {
val rr=scala.util.Random
if (rr.nextFloat() < ratio) true else false
}
val ratio = 0.3
val result = input.map(x=>(x, randomSelect(ratio))).filter(x._2).map(x=>x._1)
所以我首先为每个元素附加一个真/假标签,并过滤掉那些假元素,并取回序列的子集。
有没有更快/优势的方式?
所以基本上有两种方法:
n
随机选择元素p
您的解决方案是后者,可以简化为:
l.filter(_ => r.nextFloat < p)
(从现在开始,我正在调用列表、l
实例Random
r
和您的比率p
。)
如果你想对n
元素进行精确采样,你可以这样做:
r.shuffle(l).take(n)
我比较了从 1000 个元素列表中选择 200 个元素的这些:
scala> val first = time{
| l.map(x => (x, r.nextFloat < p)).filter(_._2).map(_._1)
| }
Elapsed time: 3249507ns
scala> val second = time {
| r.shuffle(l).take(200)
| }
Elapsed time: 10640432ns
scala> val third = time{
| l.filter(_ => r.nextFloat < p)}
Elapsed time: 1689009ns
删除额外的两个maps
s 似乎可以将速度提高大约三分之一(这是完全有道理的)。shuffle-and-take 方法要慢得多,但可以保证你有固定数量的元素。
如果您想进行更严格的调查(即多次试验的平均值,而不是 1),我从这里借用了计时函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句