有效地在许多元素上寻找中位数或近似中位数

时间:2016-07-05 15:34:15

标签: apache-spark out-of-memory apache-spark-sql median

我正在使用Robust Z-Score方法使用Spark SQL在许多列中查找异常。不幸的是,这涉及计算许多中位数,遗憾的是效率非常低。我做了一些搜索,但找不到任何内置的高效库来进行近似或快速中值计算。

每次运行我的查询时,其中涉及以下“sqlContext.sql(”SELECT percentile_approx(“+ colname +”,0.5)FROM partitioned“)”,我最终收到以下错误:

Name: java.lang.OutOfMemoryError
Message: GC overhead limit exceeded

所以我假设这种方法在实践中绝对不太可用。 如果有必要,我可以发布我的部分代码(我没有,因为它目前有点复杂,但如果需要我可以)。我的数据集最多有500k点,所以你们认为这是一个效率低下的缓存(),我的数据使用问题,还是我需要一种更好的方法来找到中位数?

1 个答案:

答案 0 :(得分:0)

如果你想在问题中使用Hive UDF,你可以提供额外的参数来确定要使用的记录数量:

import org.apache.spark.mllib.random.RandomRDDs

RandomRDDs.normalRDD(sc, 100000).map(Tuple1(_)).toDF("x").registerTempTable("df")

sqlContext.sql("SELECT percentile_approx(x, 0.5, 100) FROM df").show()

// +--------------------+
// |                 _c0|
// +--------------------+
// |-0.02626781447291...|
// +--------------------+

sqlContext.sql("SELECT percentile_approx(x, 0.5, 10) FROM df").show()

// +-------------------+
// |                _c0|
// +-------------------+
// |-0.4185534605295841|
// +-------------------+

默认值为10000,因此由于相关的随机播放仍然很昂贵,因此在实践中不应该导致OOM。它表明您的配置或查询可能存在一些超出计算中值的问题。

另一方面,Spark 2.0.0提供了How to find median using Spark中描述的原生百分位近似方法。