Преобразование столбцов фрейма данных Scala во вложенный json

#json #scala #apache-spark

#json #scala #apache-spark

Вопрос:

Я пытаюсь преобразовать фрейм данных во вложенный json.

В основном конечный результат находится на уровне поля « id » с вложенным форматом json других полей.

Форматирование в формате Json с использованием поля « rank » в качестве ключа и « desc » и « percent » в качестве значений. Ценю вашу помощь!

Исходные данные:-

 val df = Seq(
  ("1", "ABC", "1","91.68"),
  ("1", "BCD", "2","89.03"),
  ("1", "DEF", "3","78.32"),
  ("1", "XYZ", "4","70.64")
).toDF("id", "desc", "rank", "percent")

 --- ---- ---- ------- 
|id |desc|rank|percent|
 --- ---- ---- ------- 
|1  |ABC |1   |91.68  |
|1  |BCD |2   |89.03  |
|1  |DEF |3   |78.32  |
|1  |XYZ |4   |70.64  |
 --- ---- ---- ------- 
  

Ожидаемый результат:

  --- -------------------------------------------------------------------------------------------------------------------------------------------------------- 
|id |json                                                                                                                                                    |
 --- -------------------------------------------------------------------------------------------------------------------------------------------------------- 
|1  |{"1":{"desc":"ABC","percent":"91.68"},"2":{"desc":"BCD","percent":"89.03"},"3":{"desc":"DEF","percent":"78.32"},"4":{"desc":"XYZ","percent":"70.64"}}   |
 --- -------------------------------------------------------------------------------------------------------------------------------------------------------- 
  

Ответ №1:

Вы можете сделать это с помощью простого UDF, чтобы исправить json так, как вам нужно:

 val toJsonUDF = udf((key: String, jsonString: String) =>  "{ "   key   ":"   jsonString   "}")
  

Затем создайте столбец json с помощью withColumn метода, используя предыдущий UDF и to_json метод, который создает jsonString из заданных столбцов:

 df.withColumn("json", toJsonUDF($"rank", to_json(struct("desc","percent"))))
  .select("id", "json")
  .groupBy("id")
  .agg(collect_list("json").as("json"))
  

ВЫХОДНОЙ СИГНАЛ

        --- ------------------------------------------------------------------------------------------------------------------------------------------------------------ 
      |id |collect_list(json)                                                                                                                                          |
       --- ------------------------------------------------------------------------------------------------------------------------------------------------------------ 
      |1  |[{ 1:{"desc":"ABC","percent":"91.68"}}, { 2:{"desc":"BCD","percent":"89.03"}}, { 3:{"desc":"DEF","percent":"78.32"}}, { 4:{"desc":"XYZ","percent":"70.64"}}]|
       --- ------------------------------------------------------------------------------------------------------------------------------------------------------------