Изменение столбца структуры в фрейме данных Spark - PullRequest
0 голосов
/ 27 мая 2020

У меня есть фрейм данных pyspark, который содержит столбец «студент» следующим образом:

"student" : {
   "name" : "kaleem",
   "rollno" : "12"
}

Схема для этого в фрейме данных:

structType(List(
   name: String, 
   rollno: String))

Мне нужно изменить этот столбец как

"student" : {
   "student_details" : {
         "name" : "kaleem",
         "rollno" : "12"
   }
}

Схема для этого в фрейме данных должна быть:

structType(List(
  student_details: 
     structType(List(
         name: String, 
         rollno: String))
))

Как это сделать в Spark?

Ответы [ 2 ]

2 голосов
/ 27 мая 2020
• 1000
scala> import za.co.absa.spark.hats.Extensions._

scala> df.printSchema
root
 |-- ID: string (nullable = true)

scala> val df2 = df.nestedMapColumn("ID", "ID", c => struct(c as alfa))

scala> df2.printSchema
root
 |-- ID: struct (nullable = false)
 |    |-- alfa: string (nullable = true)

scala> val df3 = df2.nestedMapColumn("ID.alfa", "ID.alfa", c => struct(c as "beta"))

scala> df3.printSchema
root
 |-- ID: struct (nullable = false)
 |    |-- alfa: struct (nullable = false)
 |    |    |-- beta: string (nullable = true)

Ваш запрос будет

df.nestedMapColumn("student", "student", c => struct(c as "student_details"))
1 голос
/ 28 мая 2020

Используйте функцию named_struct , чтобы добиться этого -

1. Прочтите json как столбец

val  data =
      """
        | {
        |   "student": {
        |       "name": "kaleem",
        |       "rollno": "12"
        |   }
        |}
      """.stripMargin
    val df = spark.read.json(Seq(data).toDS())
    df.show(false)
    println(df.schema("student"))

Output-

+------------+
|student     |
+------------+
|[kaleem, 12]|
+------------+

StructField(student,StructType(StructField(name,StringType,true), StructField(rollno,StringType,true)),true)

2. измените схему, используя named_struct

val processedDf = df.withColumn("student",
      expr("named_struct('student_details', student)")
    )
    processedDf.show(false)
    println(processedDf.schema("student"))

Output-

+--------------+
|student       |
+--------------+
|[[kaleem, 12]]|
+--------------+

StructField(student,StructType(StructField(student_details,StructType(StructField(name,StringType,true), StructField(rollno,StringType,true)),true)),false)

Для python step#2 будет работать как просто удалить val

...