pck*_*kmn 15 hadoop scala bigdata apache-spark
此页面包含一些统计函数(均值,stdev,方差等),但不包含中位数.如何计算准确的中位数?
谢谢
Eug*_*nev 19
您需要对RDD进行排序,并将元素放在两个元素的中间或平均值中.以下是RDD [Int]的示例:
import org.apache.spark.SparkContext._
val rdd: RDD[Int] = ???
val sorted = rdd.sortBy(identity).zipWithIndex().map {
case (v, idx) => (idx, v)
}
val count = sorted.count()
val median: Double = if (count % 2 == 0) {
val l = count / 2 - 1
val r = l + 1
(sorted.lookup(l).head + sorted.lookup(r).head).toDouble / 2
} else sorted.lookup(count / 2).head.toDouble
Run Code Online (Sandbox Code Playgroud)
使用Spark 2.0+和DataFrame API可以使用该approxQuantile
方法吗?
def approxQuantile(col: String, probabilities: Array[Double], relativeError: Double)
Run Code Online (Sandbox Code Playgroud)
从Spark版本2.2开始,它还将同时在多个列上工作。通过将和设置 probabilites
为0,它将计算出精确的中位数。从文档中:Array(0.5)
relativeError
达到的相对目标精度(大于或等于0)。如果设置为零,则将计算精确的分位数,这可能会非常昂贵。
尽管如此,将其设置relativeError
为0时,精度似乎仍然存在一些问题,请参见此处的问题。接近0的低错误在某些情况下会更好地工作(取决于Spark版本)。
一个小的工作示例,它计算1到99之间的数字中位数(包括两端值),并使用low relativeError
:
val df = (0 to 99).toDF("num")
val median = df.stat.approxQuantile("num", Array(0.5), 0.001)(0)
println(median)
Run Code Online (Sandbox Code Playgroud)
返回的中位数为50.0。
归档时间: |
|
查看次数: |
11552 次 |
最近记录: |