1. 程式人生 > >hive計算分位數

hive計算分位數

tinc width 個人 ray normal tin map row percent

hive裏面倒是有個percentile函數和percentile_approx函數,其使用方式為percentile(col, p)、percentile_approx(col, p),p(0,1)p∈(0,1)
其中percentile要求輸入的字段必須是int類型的,而percentile_approx則是數值類似型的都可以
其實percentile_approx還有一個參數B:percentile_approx(col, p,B),參數B控制內存消耗的近似精度,B越大,結果的準確度越高。默認為10,000。當col字段中的distinct值的個數小於B時,結果為準確的百分位數。
如果我要求多個分位數怎麽辦呢?,可以把p換為array(

p1,p2,p3p1,p2,p3…),即

percentile_approx(col,array(0.05,0.5,0.95),9999)percentile_approx(col,array(0.05,0.5,0.95),9999)


如果不放心的話,就給col再加個轉換:

percentile_approx(cast(col as double),array(0.05,0.5,0.95),9999)percentile_approx(cast(col as double),array(0.05,0.5,0.95),9999)


其輸出結果長這樣:

[0.0,4001.0,4061.0][0.0,4001.0,4061.0]


沒法直接用啊!再加個轉換:

explode(percentile_approx(cast(col as double),array(0.05,0.5,0.95),9999))as percentileexplode(percentile_approx(cast(col as double),array(0.05,0.5,0.95),9999))as percentile


輸出結果就長這樣了:

percentile
0
4001
4061

實際操作中,發現有時在計算分位數的時候mapper會卡在0%。
前面說過,如果distinct的值小於B,就會返回精確值,那麽個人猜測是因為後臺執行的過程是先做了一個select distinct limit B,然後排序得到分位數。如果distinct值特別多的情況下,僅僅是去重就是一個巨大的運算負擔,更別說排序了。而當把B從10000調到100的時候很快就能跑出來了

hive計算分位數