为什么Spark RDD上的rdd.sample()
函数返回不同数量的元素,即使fraction参数相同?例如,如果我的代码如下所示:
val a = sc.parallelize(1 to 10000, 3)
a.sample(false, 0.1).count
每次运行代码的第二行时,它返回一个不等于1000的不同数字。实际上我希望每次都能看到1000,尽管1000个元素可能不同。谁能告诉我如何获得样本大小恰好等于1000的样本?非常感谢你。
答案 0 :(得分:22)
如果您需要精确样本,请尝试
a.takeSample(false, 1000)
但请注意,这会返回一个数组,而不是RDD
。
至于为什么a.sample(false, 0.1)
没有返回相同的样本大小:因为spark内部使用了一个名为Bernoulli sampling的东西来获取样本。 fraction
参数不代表RDD实际大小的分数。它表示人口中每个元素被选为样本的概率,并且维基百科说:
因为样本的每个元素都是单独考虑的,所以样本大小不是固定的,而是遵循二项分布。
这实质上意味着这个数字不会保持不变。
如果您将第一个参数设置为true
,那么它将使用名为Poisson sampling的内容,这也会导致非确定性的结果样本大小。
<强>更新强>
如果您希望坚持使用sample
方法,则可以为fraction
参数指定更大的概率,然后按以下方式调用take
:
a.sample(false, 0.2).take(1000)
大部分时间,但不一定总是,这应该导致样本量为1000.如果你有足够多的人口,这可能会有效。
答案 1 :(得分:4)
另一种方法可以是先取样然后再制作RDD。对于大型数据集,这可能会很慢。
sc.makeRDD(a.takeSample(false, 1000, 1234))