我正在使用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点,所以你们认为这是一个效率低下的缓存(),我的数据使用问题,还是我需要一种更好的方法来找到中位数?
答案 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中描述的原生百分位近似方法。