Альтернатива CASE WHEN для создания бинов из столбца - PullRequest
2 голосов
/ 18 марта 2020

У меня есть таблица, где столбец (COL1) может иметь значения от 0 до 1 (включительно). Из этого столбца я хотел бы создать новый столбец, который классифицирует COL1, используя предопределенные диапазоны (т. Е. Создает ячейки). Когда количество категорий / корзин мало, это легко сделать с помощью CASE WHEN, например:

SELECT
       CASE WHEN COL1 <= 0.2 THEN 1
            WHEN COL1 > 0.2 AND COL1 <= 0.4 THEN 2
            ....
            WHEN COL1 > 0.8 AND COL1 <= 1 THEN 5
       END AS COL1_bin
FROM   Table

Поскольку я хотел бы иметь 100 корзин, я ищу способ сделать это больше «автоматически» с помощью функции, где я могу, например, дать минимальный, максимальный и размер шага / размер бина (например, min = 0, max = 1, stepsize = 0.01)

Я делаю это в HiveQL, который должен быть очень похож на MySQL.

Ответы [ 2 ]

2 голосов
/ 18 марта 2020

Вот способ сделать это. Если предположить, что вы хотите, чтобы диапазоны бинов были 0,1,0,2,0,3, ... до 1. Затем вы сгенерируете 10 строк, используя блок row_gen и устанавливая step_size как row_number / 10, а также устанавливая lower_limit и upper_limit для каждый бин.

После этого вам нужно будет проверить, подходит ли значение для col1 в соответствующую нижнюю и верхнюю границы бина следующим образом. (Я использовал левое соединение, чтобы включить те условия, в которых значение col1 равно нулю. Если это маловероятный сценарий, его можно изменить на обычное соединение)

with row_gen 
  as (select top 10 
             ,row_number() over(order by 1) as bin_id
             ,row_number() over(order by 1)/10 as as lower_limit
             ,row_number() over(order by 1)/10 + 1/10 as as upper_limit
        from table /*any table that has 10 rows*/ 
      )
   select a.*
          ,b.bin_id
     from your_table a
left join row_gen b
       on a.col1 between b.lower_rnk and b.upper_rnk
1 голос
/ 18 марта 2020

Я не уверен, имеет ли Hive функцию биннинга (Postgres имеет). Но вы можете использовать арифметику c:

select floor( greatest(least($maxval, col1), $minval) - $minval) /
              $step_size
            ) as bin
from t;

Если вам нужны минимальное и максимальное значения из данных, вы можете использовать оконные функции:

select floor( greatest(least(maxval, col1), minval) - minval) /
              $step_size
            ) as bin
from (select t.*,
             min(col1) over () as minval,
             max(col1) over () as maxval
      from t
     ) t;

Строго говоря, вы не не нужен подзапрос для расчета. Но это позволяет использовать bin для агрегирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...