我试图获得单列数据框的0.8%。我以这种方式尝试过:

val limit80 = 0.8
val dfSize = df.count()
val perfentileIndex = dfSize*limit80

dfSorted = df.sort()
val percentile80 = dfSorted .take(perfentileIndex).last()


但是我认为这对于大数据帧将失败,因为它们可能分布在不同的节点上。

有没有更好的方法来计算百分位数?或者我怎么能在同一台机器上拥有数据帧的所有行(即使那是非常反模式的),所以df.take(index)实际上会考虑整个数据集,而不仅仅是节点中的分区。

最佳答案

对于Spark 2.x,可以使用approxQuantile,如以下示例所示:

val df = Seq(
  10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  20, 21, 22, 23, 24, 25, 26, 27, 28, 29
).toDF("num")

df.stat.approxQuantile("num", Array(0.8), 0.1)
// res4: Array[Double] = Array(26.0)


请注意,第三个参数relativeError越小,计算的成本就越高。这是API文档中的相关说明:


relativeError:要达到的相对目标精度(大于
或等于0)。如果设置为零,则将计算精确的分位数,
这可能非常昂贵。

10-02 02:52
查看更多