2016-07-05 30 views
0

我正在使用強大的Z-Score方法來查找使用Spark SQL的許多列中的異常。不幸的是,這涉及到計算許多中位數,不幸的是效率很低。我做了一些搜索,但找不到任何內置的高效庫來進行近似或快速的中值計算。在許多元素上高效地找到中值或近似中值

每次運行我的查詢,其涉及下面的 「sqlContext.sql(」 選擇percentile_approx( 「+ colname的+」,0.5)FROM分配 「)」,我最終接收以下錯誤:

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

所以我假設這種方法在實踐中絕對不是太可用。 如果有必要,我可以發佈我的代碼的一部分(我還沒有,因爲它現在有點複雜,但如果需要,我可以)。我的數據集最多隻有500k點,所以你們認爲這是一個緩存效率低下的問題,還是我的數據使用問題,還是我需要更好的方法來找到中值?

+0

爲什麼不只是對元素進行排序並取大小/第2個元素?這是更快更容易 – GameOfThrows

+0

@GameOfThrows有沒有一個好的方法來做到這一點,而不必定義一個新的DataFrame?目前我對Spark比較陌生。 –

+0

如果是這樣,它從未成爲Spark的一部分。這只是一個Hive代碼,恰好與Spark兼容。 – zero323

回答

0

如果你想使用蜂巢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中所述。

相關問題