Attualmente, per classificare percentile una colonna nell'alveare, sto usando qualcosa come la seguente. Sto cercando di classificare gli elementi in una colonna in base a quale percentile essi rientrano, assegnando un valore da 0 a 1 a ciascun elemento. Il codice seguente assegna un valore compreso tra 0 e 9, in sostanza dicendo che un articolo con uno char_percentile_rank
di 0 si trova nel 10% inferiore degli articoli e un valore pari a 9 è nel 10% superiore degli articoli. C'è un modo migliore per farlo?Hive: esiste un modo migliore per classificare una colonna?
select item
, characteristic
, case when characteristic <= char_perc[0] then 0
when characteristic <= char_perc[1] then 1
when characteristic <= char_perc[2] then 2
when characteristic <= char_perc[3] then 3
when characteristic <= char_perc[4] then 4
when characteristic <= char_perc[5] then 5
when characteristic <= char_perc[6] then 6
when characteristic <= char_perc[7] then 7
when characteristic <= char_perc[8] then 8
else 9
end as char_percentile_rank
from (
select split(item_id,'-')[0] as item
, split(item_id,'-')[1] as characteristic
, char_perc
from (
select collect_set(concat_ws('-',item,characteristic)) as item_set
, PERCENTILE(BIGINT(characteristic),array(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)) as char_perc
from(
select item
, sum(characteristic) as characteristic
from table
group by item
) t1
) t2
lateral view explode(item_set) explodetable as item_id
) t3
Nota: ho dovuto fare il collect_set
al fine di evitare un self join, come la funzione percentile esegue implicitamente una group by
.
Ho notato che la funzione percentile è orribilmente lenta (almeno in questo utilizzo). Forse sarebbe meglio calcolare manualmente il percentile?
La funzione percentile ha bisogno di avere un gruppo - è per questo che ho fatto la collect_set apparentemente inutili (concat_ws (...)) - in modo da renderlo uno gruppo. Se invece raggruppo per articolo e caratteristica, allora percentili per articolo e caratteristica, che non voglio. Qualche idea su come evitarlo? –
L'ho capito quasi subito dopo aver dormito su di esso e tornare ad esso. Basta aggiungere() sul percentile. Quindi la riga dovrebbe contenere: PERCENTILE (BIGINT (caratteristica), array (0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)) over() come char_perc. Ma sembra che sia la mia query originale che quella nuova abbiano prestazioni molto simili. –
@CharlieHaley è possibile fare riferimento a 'PERCENTILE (BIGINT ...) [i]' dove 'i = 0-8'? In tal caso, è possibile spostare l'istruzione case e rimuovere 1 tabella derivata – FuzzyTree