我想从Scala列表或数组(不是RDD)中随机采样,样本大小可以比列表或数组的长度长得多,我如何有效地执行此?因为样本大小可能非常大,并且采样(在不同的列表/数组上)需要进行大量的次数。
我知道对于Spark RDD我们可以使用takeSample()来做,有没有Scala list/array的等价物?
非常感谢。
发布于 2015-10-04 19:20:06
一个易于理解的版本将如下所示:
import scala.util.Random
Random.shuffle(list).take(n)
Random.shuffle(array.toList).take(n)
// Seeded version
val r = new Random(seed)
r.shuffle(...)
发布于 2015-10-04 18:25:31
对于数组:
import scala.util.Random
import scala.reflect.ClassTag
def takeSample[T:ClassTag](a:Array[T],n:Int,seed:Long) = {
val rnd = new Random(seed)
Array.fill(n)(a(rnd.nextInt(a.size)))
}
基于您的种子创建一个随机数生成器(rnd
)。然后,用从0到数组大小的随机数填充数组。
最后一步是将每个随机值应用于输入数组的索引运算符。在REPL中使用它可能如下所示:
scala> val myArray = Array(1,3,5,7,8,9,10)
myArray: Array[Int] = Array(1, 3, 5, 7, 8, 9, 10)
scala> takeSample(myArray,20,System.currentTimeMillis)
res0: scala.collection.mutable.ArraySeq[Int] = ArraySeq(7, 8, 7, 3, 8, 3, 9, 1, 7, 10, 7, 10,
1, 1, 3, 1, 7, 1, 3, 7)
对于列表,我只需将列表转换为Array并使用相同的函数。不管怎样,我怀疑你能更有效地处理列表。
需要注意的是,使用列表的相同函数将花费O(n^2)时间,而首先将列表转换为数组将花费O(n)时间
发布于 2017-02-26 09:38:28
如果你想不替换样本--用随机数压缩,排序O(n*log(n)
,丢弃随机数,取
import scala.util.Random
val l = Seq("a", "b", "c", "d", "e")
val ran = l.map(x => (Random.nextFloat(), x))
.sortBy(_._1)
.map(_._2)
.take(3)
https://stackoverflow.com/questions/32932229
复制相似问题