Spark DataFrame - 选择n个随机行

lte*_*e__ 13 java dataframe apache-spark

我有一个包含数千条记录的数据框,我想随机选择1000行到另一个数据框进行演示.我怎么能用Java做到这一点?

谢谢!

小智 23

您可以随机播放行,然后选择最上面的行:

import org.apache.spark.sql.functions.rand

dataset.orderBy(rand()).limit(n)
Run Code Online (Sandbox Code Playgroud)

  • 这种实施有效吗?订购费用是多少? (4认同)
  • 非常简单,但是效率很低。如果您对行数比较满意,则最好使用过滤器而不是分数,而不是对整个随机向量进行填充和排序以获得“ n”个最小值 (3认同)

s51*_*510 7

在 Pyspark >= 中3.1,尝试以下操作:

sdf.sample(fraction=1.0).limit(n)
Run Code Online (Sandbox Code Playgroud)


T. *_*ęda 6

您可以尝试sample()方法。不幸的是,您必须给数字而不是分数。您可以这样编写函数:

def getRandom (dataset : Dataset[_], n : Int) = {
    val count = dataset.count();
    val howManyTake = if (count > n) n else count;
    dataset.sample(0, 1.0*howManyTake/count).limit (n)
}
Run Code Online (Sandbox Code Playgroud)

说明:我们必须获取一小部分数据。如果我们有2000行,而您想获得100行,则必须有0.5行。如果要获得比DataFrame多的行,则必须得到1.0。调用limit()函数以确保舍入没有问题,并且得到的行数不超过指定的数。

编辑:我在其他答案中看到takeSample方法。但要记住:

  1. 它是RDD的一种方法,而不是Dataset的一种,因此您必须这样做: dataset.rdd.takeSample(0, 1000, System.currentTimeMilis()).toDF() takeSample将收集所有值。
  2. 请记住,如果要获取很多行,则OutOfMemoryError会出现问题,因为takeSample在驱动程序中收集结果。小心使用

  • 有没有办法在不计算数据帧的情况下完成此操作,因为此操作在大型 DF 中成本太高。 (2认同)
  • @Hasson尝试缓存DataFrame,因此第二个操作会快得多。或者你也可以使用approxQuantile函数,它会更快但不太精确 (2认同)