Создание столбцов из значений динамически - PullRequest
0 голосов
/ 15 января 2020

В нашем проекте мы используем один ETL каркас (встроенный PySpark), который принимает Spark-sql операторы для преобразования данных из источника и загрузки Hive внешних таблиц.

Теперь у меня есть требование прочитать таблицу, а затем выбрать уникальные значения одного столбца и затем динамически создать таблицу Hive с таким количеством столбцов.

Для примера рассмотрите таблицы ниже.

День 1:

qstn_mstr:

prsnid | qstn 
1 | satisfactory
2 | survey 
3 | review

Структура целевой таблицы:

prsnid | satisfactory | survey | review

В день 1: в приведенном выше примере есть 3 уникальные значения в столбце qstns и, следовательно, выходная таблица создается с этими 3 значениями в виде столбцов.

В День 2: Скажи нет. уникальных значений в столбце qstn в таблице Qstn_mster изменяется на 5 (может увеличиваться или уменьшаться), что, в свою очередь, влияет на номер столбцов в целевой таблице, которые теперь должны содержать 5 столбцов.

День 2:

qstn_mstr:

prsnid | qstn 
1 | satisfactory
2 | survey 
3 | review 
4 | validity
5 | vote

Структура целевой таблицы:

prsnid | satisfactory | survey | review | validity | vote

Следовательно, каждый день структура целевой таблицы будет динамически меняться.

Как лучше всего спроектировать / смоделировать такое требование в среде PySpark с таблицами Hive?

Пожалуйста, поделитесь своими мыслями.

1 Ответ

0 голосов
/ 30 января 2020

Если намерение состоит в том, чтобы применить некоторые вычисления к каждому столбцу, например, подсчет или различный и т. Д. Тогда можно использовать pivot

Пример:

df = sqlContext.createDataFrame(
    [[1, "satisfactory"],
     [2, "survey"],
     [3, "review"],
     [4, "validity"],
     [5, "vote"],], 
    ["prsn_id", "qstn"])

(df
.groupBy(["prsn_id"])
.pivot("qstn")
.agg({"prsn_id": "count"})
.fillna(0)
.orderBy(["prsn_id"])
.show())

Вывод:

+-------+------+------------+------+--------+----+
|prsn_id|review|satisfactory|survey|validity|vote|
+-------+------+------------+------+--------+----+
|      1|     0|           1|     0|       0|   0|
|      2|     0|           0|     1|       0|   0|
|      3|     1|           0|     0|       0|   0|
|      4|     0|           0|     0|       1|   0|
|      5|     0|           0|     0|       0|   1|
+-------+------+------------+------+--------+----+

Но если целью является просто создать эти столбцы и сказать, установить их на 0 сейчас:

column_list = [psf.lit(0).alias(col[0]) 
               for col in 
               df.select("qstn")
               .distinct().collect()]


df.select(["prsn_id"] + column_list).show()

Вывод:

+-------+----+--------+------+------+------------+
|prsn_id|vote|validity|survey|review|satisfactory|
+-------+----+--------+------+------+------------+
|      1|   0|       0|     0|     0|           0|
|      2|   0|       0|     0|     0|           0|
|      3|   0|       0|     0|     0|           0|
|      4|   0|       0|     0|     0|           0|
|      5|   0|       0|     0|     0|           0|
+-------+----+--------+------+------+------------+
...