Изменение порядка полей во вложенном фрейме данных - PullRequest
1 голос
/ 17 октября 2019

Как изменить порядок полей во вложенном фрейме данных в Scala? Например, ниже приведены ожидаемые и желаемые схемы

currently->

root
 |-- domain: struct (nullable = false)
 |    |-- assigned: string (nullable = true)
 |    |-- core: string (nullable = true)
 |    |-- createdBy: long (nullable = true)
 |-- Event: struct (nullable = false)
 |    |-- action: string (nullable = true)
 |    |-- eventid: string (nullable = true)
 |    |-- dqid: string (nullable = true)

expected->

 root
 |-- domain: struct (nullable = false)
 |    |-- core: string (nullable = true)
 |    |-- assigned: string (nullable = true)
 |    |-- createdBy: long (nullable = true)
 |-- Event: struct (nullable = false)
 |    |-- dqid: string (nullable = true)
 |    |-- eventid: string (nullable = true)
 |    |-- action: string (nullable = true)
    ```

Ответы [ 2 ]

0 голосов
/ 17 октября 2019

Вам необходимо определить schema перед прочтением кадра данных.

val schema = val schema = StructType(Array(StructField("root",StructType(Array(StructField("domain",StructType(Array(StructField("core",StringType,true), StructField("assigned",StringType,true), StructField("createdBy",StringType,true))),true), StructField("Event",StructType(Array(StructField("dqid",StringType,true), StructField("eventid",StringType,true), StructField("action",StringType,true))),true))),true)))

Теперь вы можете применить эту схему при чтении файла.

val df = spark.read.schema(schema).json("path/to/json")

Должно работать с любымвложенные данные.

Надеюсь, это поможет!

0 голосов
/ 17 октября 2019

Наиболее эффективный подход может заключаться в select вложенных элементах и ​​переносе в пару struct с, как показано ниже:

case class Domain(assigned: String, core: String, createdBy: Long)
case class Event(action: String, eventid: String, dqid: String)

val df = Seq(
  (Domain("a", "b", 1L), Event("c", "d", "e")),
  (Domain("f", "g", 2L), Event("h", "i", "j"))
).toDF("domain", "event")

val df2 = df.select(
  struct($"domain.core", $"domain.assigned", $"domain.createdBy").as("domain"),
  struct($"event.dqid", $"event.action", $"event.eventid").as("event")
)

df2.printSchema
// root
//  |-- domain: struct (nullable = false)
//  |    |-- core: string (nullable = true)
//  |    |-- assigned: string (nullable = true)
//  |    |-- createdBy: long (nullable = true)
//  |-- event: struct (nullable = false)
//  |    |-- dqid: string (nullable = true)
//  |    |-- action: string (nullable = true)
//  |    |-- eventid: string (nullable = true)

Альтернативой может быть применение по строкам map:

import org.apache.spark.sql.Row

val df2 = df.map{ case Row(Row(as: String, co: String, cr: Long), Row(ac: String, ev: String, dq: String)) =>
  ((co, as, cr), (dq, ac, ev))
}.toDF("domain", "event")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...