approxQuantile 在 Spark (Scala) 中给出不正确的中位数?
Posted
技术标签:
【中文标题】approxQuantile 在 Spark (Scala) 中给出不正确的中位数?【英文标题】:approxQuantile give incorrect Median in Spark (Scala)? 【发布时间】:2017-03-08 10:52:59 【问题描述】:我有这个测试数据:
val data = List(
List(47.5335D),
List(67.5335D),
List(69.5335D),
List(444.1235D),
List(677.5335D)
)
我预计中位数为 69.5335。 但是当我尝试使用此代码找到确切的中位数时:
df.stat.approxQuantile(column, Array(0.5), 0)
它给了我:444.1235
为什么会这样?如何解决?
我是这样做的:
val data = List(
List(47.5335D),
List(67.5335D),
List(69.5335D),
List(444.1235D),
List(677.5335D)
)
val rdd = sparkContext.parallelize(data).map(Row.fromSeq(_))
val schema = StructType(Array(
StructField("value", DataTypes.DoubleType, false)
))
val df = sqlContext.createDataFrame(rdd, schema)
df.createOrReplaceTempView(tableName)
val df2 = sc.sql(s"SELECT value FROM $tableName")
val median = df2.stat.approxQuantile("value", Array(0.5), 0)
所以我正在创建临时表。然后在里面搜索,然后计算结果。只是为了测试。
【问题讨论】:
我遇到了同样的问题。关于如何解决这个问题的任何建议? @Nimi 我记得我已经用自己的 udf 解决了它。 您介意分享一下吗?我不知道如何使用 udf 聚合列的值。我想将计算保留在 spark 中,而不是提取值。 【参考方案1】:请注意,这是一个近似分位数计算。它不应该一直给你确切的答案。请参阅here 以获得更详尽的解释。
原因是对于非常大的数据集,有时你可以得到一个近似答案,只要你得到它比精确计算快得多。
【讨论】:
但在文档spark.apache.org/docs/2.0.2/api/java/org/apache/spark/sql/… 中,他们声明 relativeError - 要达到的相对目标精度 (>= 0)。如果设置为零,则计算精确的分位数【参考方案2】:这是我本地的结果。你有类似的事情吗?
val data = List(
List(47.5335D),
List(67.5335D),
List(69.5335D),
List(444.1235D),
List(677.5335D)
)
val df = data.flatten.toDF
df.stat.approxQuantile("value", Array(0.5), 0)
// res18: Array[Double] = Array(67.5335)
【讨论】:
嗯,奇怪。另一个版本,但仍然不是 69.5335。我已将所有来源添加到我的问题中。【参考方案3】:我在尝试将 approxQuantile() 方法与Spark-2.2.1
一起使用时遇到了类似的问题。当我升级到 Spark-2.4.3
时,approxQuantile() 现在返回正确的中位数。
【讨论】:
以上是关于approxQuantile 在 Spark (Scala) 中给出不正确的中位数?的主要内容,如果未能解决你的问题,请参考以下文章
Jerry's spark demo application