本文来介绍分位数的含义以及Hive中如何使用计算任意分位数(包括中位数)的函数。
分位数(Quantile),亦称分位点,是指将有限的数集中的所有值,从小到大排序后分为几个等份的数值点。常用的有中位数(即二分位数)、四分位数、十分位数等。
计算有限个数的数据的二分位数的方法是:把所有的同类数据按照大小的顺序排列。如果数据的个数是奇数,则中间那个数据就是这群数据的中位数;如果数据的个数是偶数,则中间那两个数据的算术平均值就是这群数据的中位数。
四分位数(Quartile)是统计学中分位数的一种,即把所有数值由小到大排列并分成四等份,处于三个分割点位置的数值就是四分位数。
其余的十分位数、百分位数、千分位数的算法以此类推。
返回类型 |
函数名 |
描述 |
DOUBLE |
percentile(BIGINT col, p) |
返回组内某个列精确的第p位百分数,p必须在0和1之间,如果p为0.5,则返回中位数。 |
array |
percentile(BIGINT col, array(p1 [, p2]...)) |
返回组内某个列精确的第p1,p2,……位百分数,p必须在0和1之间。 |
DOUBLE |
percentile_approx(DOUBLE col, p [, B]) |
返回组内数字列近似的第p位百分数(包括浮点数),参数B控制近似的精确度,B值越大,近似度越高,默认值为10000。当列中非重复值的数量小于B时,返回精确的百分数。 |
array |
percentile_approx(DOUBLE col, array(p1 [, p2]...) [, B]) |
同上,但接受并返回百分数数组。 |
新建test.txt文件,输入两列数据,假设第一列为公司名,第二列为各公司各月销售额,单位为万元。shop1有10个月的数据,分别为1到10,未排序;shop2有11个月的数据,分别为1到11,未排序。
[root@hadoop ~]# vim test.txt
shop1,1
shop1,3
shop1,2
shop1,4
shop1,6
shop1,5
shop1,7
shop1,9
shop1,8
shop1,10
shop2,1
shop2,2
shop2,5
shop2,3
shop2,6
shop2,9
shop2,7
shop2,8
shop2,4
shop2,10
shop2,11
新建表temp_test4,将test文件中的数据插入,查看数据
CREATE TABLE temp_test4 (
shop STRING
,chengben INT
) row format delimited fields terminated BY ',';
load data local inpath '/root/test.txt' into table temp_test4;
hive (app)> select * from temp_test4;
OK
shop1 1
shop1 3
shop1 2
shop1 4
shop1 6
shop1 5
shop1 7
shop1 9
shop1 8
shop1 10
shop2 1
shop2 2
shop2 5
shop2 3
shop2 6
shop2 9
shop2 7
shop2 8
shop2 4
shop2 10
shop2 11
功能:求col列构成的数据集中准确的第p百分位数,p必须介于0和1之间,col字段只支持整数,返回一个DOUBLE类型的分位数值。当p为0.5时,返回值为中位数,当p为0.25时,返回第一四分位数,其他分位数依此类推。
计算shop1和shop2的成本中位数
hive (app)> SELECT shop
> ,percentile(chengben, 0.5)
> FROM temp_test4
> GROUP BY shop;
OK
shop _c1
shop1 5.5
shop2 6.0
shop1有10个数据,从小到大排序后中间的两个数为5和6,所以中位数为5.5
shop1有11个数据,从小到大排序后最中间的数6,所以中位数为6.0
功能:和上文语法类似,但第二个参数为数组格式,可以输入多个百分位数。返回值类型也为array
计算shop1和shop2的成本第一四分位数,中位数,第三四分位数
hive (app)> SELECT shop
> ,percentile(chengben, array(0.25,0.5,0.75))
> FROM temp_test4
> GROUP BY shop;
shop _c1
shop1 [3.25,5.5,7.75]
shop2 [3.5,6.0,8.5]
功能:求近似的第p个百分位数,p必须介于0和1之间,返回值类型为double,col字段支持浮点类型。参数B控制近似精度,B越大,结果的准确度越高,参数B如果不填则使用默认值10000。
官网说数据集的去重值个数小于第三个参数时,会返回精确的分位数值,但是实测发现返回的依然是近似值,只是如果数据集的去重值个数小于第三个参数时,近似值会最接近值真实分位数值。如果数据集的去重值个数大于第三个参数,近似值则会更加的不精确。
应用场景:当数据量很大时,上一个精确的分位数值可能无法运行成功或耗时很长,可以考虑使用近似分位数函数代替。
计算中位数的近似值,第三个参数填任意一个大于数据集去重的个数的值
hive (app)> SELECT shop
> ,percentile_approx(chengben, 0.5, 11)
> FROM temp_test4
> GROUP BY shop;
shop _c1
shop1 5.0
shop2 5.5
数据集去重的个数小于10000时,可以不填第三个参数,结果和填一个大于数据集去重的个数的值是一样的
hive (app)> SELECT shop
> ,percentile_approx(chengben, 0.5)
> FROM temp_test4
> GROUP BY shop;
shop _c1
shop1 5.0
shop2 5.5
当第三个参数小于数据集去重的个数小于时,会返回更加不精准的近似值
hive (app)> SELECT shop
> ,percentile_approx(chengben, 0.5 ,5)
> FROM temp_test4
> GROUP BY shop;
shop _c1
shop1 4.5
shop2 5.0
功能:和上文语法类似,但第二个参数为数组格式,可以输入多个百分位数。返回值类型也为array
hive (app)> SELECT shop
> ,percentile_approx(chengben, array(0.25,0.5,0.75),11)
> FROM temp_test4
> GROUP BY shop;
shop _c1
shop1 [2.5,5.0,7.5]
shop2 [2.75,5.5,8.25]
能看到这里的同学,就右上角点个赞吧,3Q~