我试图获得单列数据框的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)。如果设置为零,则将计算精确的分位数,
这可能非常昂贵。