Hive SQL применяет запрос ко многим столбцам - PullRequest
0 голосов
/ 03 июля 2018

Я очень плохо знаком с Hive SQL и пытаюсь применить запрос ко многим столбцам. Вот запрос:

select good_at_name, cnt
, case when cnt <= char_perc[0] then 0
    when cnt <= char_perc[1] then 1
    when cnt <= char_perc[2] then 2
    else 3
  end as char_percentile_rank
from (
 select good_at_name, cnt
     , PERCENTILE(BIGINT(cnt),array(0.25, 0.5, 0.75, 1)) over () as c_perc 
 from (
   select good_at_name
     , sum(cnt) as cnt             
   from good_at_name_walmart
   group by good_at_name            
 ) t1
) t2

По сути, этот запрос создает новый столбец на основе существующего столбца и возвращает 4 группы процентилей (% 25,% 50,% 75 и% 100) для каждого значения данных. (1-й Qt, 2-й Qt, 3-й Qt, 4-й Qt в статистике). Вот мой вклад:

In [182]: data_set
Out[182]: 
  c_1  C_2  ...  C_1000
0  2    3          2
1  1    1          1    
2  2    2          0    
3  2    5          1     
4  4    1          3      

Поэтому, когда я применяю этот запрос, я получаю:

In [182]: result
Out[182]: 
  c_1  c_perc  C_2   ...   C_1000 
0  1    0       1             0     
1  2    1       1             1     
2  2    1       2             1     
3  2    1       3             2     
4  4    3       5             3     

, который возвращает c_perc только для одного столбца, например c_1. Я ищу способ применить этот запрос ко всем столбцам, чтобы получить этот вывод:

In [182]: result
Out[182]: 
  c_1  c_perc1  C_2  c_perc2  ...  C_1000  c_perc1000
0  1      0      1      0            0         0
1  2      1      1      0            1         1
2  2      1      2      1            1         1
3  2      1      3      2            2         2
4  4      3      5      3            3         3  

Любая реализация в Scala, Hive или Spark или около того будет принята с благодарностью.

1 Ответ

0 голосов
/ 03 июля 2018

Есть несколько способов подойти к этому. На высоком уровне, может быть, что-то вроде этого:

  1. Загрузить таблицу кустов в DataFrame
  2. Из кадра данных получите столбцы df.schema.fields
  3. Для каждого поля создайте новый фрейм данных со всеми новыми столбцами (вам придется переписать ваш запрос улья в spark sql)

Редактировать: Вот быстрый старт, который я бросил вместе. Извините, у меня нет больше времени, чтобы это уточнить, но, надеюсь, это иллюстрирует то, что я думал.

val schema = sql.types.StructType(List(
  sql.types.StructField("lions", sql.types.IntegerType, nullable = false),
  sql.types.StructField("tigers", sql.types.IntegerType, nullable = false),
  sql.types.StructField("bears", sql.types.IntegerType, nullable = false)
))
val rows = Seq(
  sql.Row(15,10,20),
  sql.Row(20,20,30),
 sql.Row(35,30,40),
  sql.Row(40,40,50),
  sql.Row(50,50,60)
)
val rdd = spark.sparkContext.parallelize(rows)
val df = spark.createDataFrame(rdd, schema)
df.createOrReplaceTempView("tbl")
val percentileDfs = df.schema.fields.map(field => {
  spark.sql(s"select percentile(${field.name}, array(0.25, 0.5, 0.75, 1)) as ${field.name}_centiles from tbl")
})
percentileDfs.foreach(_.show())

Выход:

+--------------------+

|      lions_centiles|

+--------------------+

|[20.0, 35.0, 40.0...|

+--------------------+ 

+--------------------+

|     tigers_centiles|

+--------------------+

|[20.0, 30.0, 40.0...|

+--------------------+

+--------------------+

|      bears_centiles|

+--------------------+

|[30.0, 40.0, 50.0...|

+--------------------+

Видите, как я перебираю поля на df.schema? Тогда вы, вероятно, просто соберете выходные данные из каждого запроса, а затем будете использовать его для генерации новых столбцов (посмотрите спарк withColumn).

...