我有一个如下所示的消费者表格。
consumer | product | quantity-------- | ------- | --------a | x | 3a | y | 4a | z | 1b | x | 3b | y | 5c | x | 4
我希望为每个消费者分配一个’归一化’的排名,以便我可以轻松地将表格分割用于测试和训练。我在Hive中使用了dense_rank(),因此得到了下面的表格。
rank | consumer | product | quantity---- | -------- | ------- | --------1 | a | x | 31 | a | y | 41 | a | z | 12 | b | x | 32 | b | y | 53 | c | x | 4
这很好,但我想将其扩展以适用于任意数量的消费者,因此我希望排名范围在0到1之间,像这样。
rank | consumer | product | quantity---- | -------- | ------- | --------0.33 | a | x | 30.33 | a | y | 40.33 | a | z | 10.67 | b | x | 30.67 | b | y | 51 | c | x | 4
这样,我将始终知道排名的范围,并且可以以标准方式分割数据(排名 <= 0.7 为训练,排名 > 0.7 为测试)
在Hive中是否有办法实现这一点?
或者,有没有其他更好的方法来解决我最初的数据分割问题?
我尝试使用select * where rank < 0.7*max(rank)
,但Hive表示MAX UDAF在where子句中尚不可用。
回答:
percent_rank
select percent_rank() over (order by consumer) as pr ,* from mytable;
+-----+----------+---------+----------+| pr | consumer | product | quantity |+-----+----------+---------+----------+| 0.0 | a | z | 1 || 0.0 | a | y | 4 || 0.0 | a | x | 3 || 0.6 | b | y | 5 || 0.6 | b | x | 3 || 1.0 | c | x | 4 |+-----+----------+---------+----------+
对于过滤,你需要使用子查询/CTE
select *from (select percent_rank() over (order by consumer) as pr ,* from mytable ) twhere pr <= ...;