【问题标题】:Finding medians or approximate medians on many elements efficiently有效地查找许多元素的中位数或近似中位数
【发布时间】:2016-07-05 15:34:15
【问题描述】:

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

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

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

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

【问题讨论】:

  • 为什么不对元素进行排序并取 size/2 个元素呢?它更快更容易
  • @GameOfThrows 有没有一种好方法可以在不需要定义新的 DataFrame 的情况下做到这一点?目前我对 Spark 比较陌生。
  • 如果是这样,它就不是 Spark 的一部分。它只是一个 Hive 代码,恰好与 Spark 兼容。

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


【解决方案1】:

如果您想在问题中使用 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,因此虽然由于相关的 shuffle 仍然很昂贵,但实际上不应导致 OOM。它表明您的配置或查询可能存在超出中位数计算本身的其他问题。

附带说明,Spark 2.0.0 提供了一种原生百分位近似方法,如 How to find median using Spark 中所述。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-23
    • 2015-01-31
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多