Как преобразовать массивоподобную строку в массив в spark-dataframe (Scala api)? - PullRequest
0 голосов
/ 19 мая 2019

У меня следующий искровой фрейм:

published   data
2019-05-15T10:37:22+00:00   [{"@id":"1","@type":"type","category":"cat"},{"@id":"2","@type":"type","category":"cat1"}]

со следующей схемой:

root
 |-- published: string (nullable = true)
 |-- data: string (nullable = true)

Второй столбец «data» - это не массив, а массивоподобная строка.

Есть ли способ изящно преобразовать такую ​​строку в объект последовательности, чтобы я мог разбивать различные @ids на отдельные строки?

Спасибо!

P.S. Код для создания df:

val df = Seq(("2019-05-15T10:37:22+00:00", """[{"@id":"1","@type":"type","category":"cat"},{"@id":"2","@type":"type","category":"cat1"}]""")).toDF("published", "data")

Ответы [ 2 ]

2 голосов
/ 19 мая 2019

В последних версиях Spark (начиная с 2.3.0) вы также можете использовать from_json со схемой, заданной в виде строки DDL (раньше это был API-интерфейс только для Java):

val schema = "array<map<`@id`: string, `@type`: string, category: string>>"

df.select($"published", from_json($"data", schema, Map.empty[String,String]) as "data")
  .select($"published", explode($"data") as "data")
  .select($"published", $"data.@id", $"data.category")
  .show(false)
+-------------------------+---+--------+
|published                |@id|category|
+-------------------------+---+--------+
|2019-05-15T10:37:22+00:00|1  |cat     |
|2019-05-15T10:37:22+00:00|2  |cat1    |
+-------------------------+---+--------+

Аргумент map определяет параметры синтаксического анализа из числа тех, которые понятны читателю JSON DataFrame.

2 голосов
/ 19 мая 2019

Использование from_json:

val df = Seq(("2019-05-15T10:37:22+00:00", """[{"@id":"1","@type":"type","category":"cat"},{"@id":"2","@type":"type","category":"cat1"}]"""))
  .toDF("published", "data")

val schema = ArrayType(StructType(Array(StructField("@id", StringType))))
df.select($"published", from_json($"data", schema) as "ids")
  .select($"published", explode($"ids.@id") as "id")
  .show(20, false)

Выход:

+-------------------------+---+
|published                |id |
+-------------------------+---+
|2019-05-15T10:37:22+00:00|1  |
|2019-05-15T10:37:22+00:00|2  |
+-------------------------+---+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...