Применить withColumn к массиву pyspark - PullRequest
1 голос
/ 27 мая 2020

Вот мой код:

from pyspark.sql import *

department1 = Row(id='123456', name='Computer Science')
department2 = Row(id='789012', name='Mechanical Engineering')

Employee = Row("firstName", "lastName", "email", "salary")
employee1 = Employee('michael', 'armbrust', 'no-reply@berkeley.edu', 100000)
employee2 = Employee('xiangrui', 'meng', 'no-reply@stanford.edu', 120000)


departmentWithEmployees1 = Row(department=department1, employees=[employee1, employee2])
departmentWithEmployees2 = Row(department=department2, employees=[employee1, employee2])


departmentsWithEmployeesSeq1 = [departmentWithEmployees1, departmentWithEmployees2]
df1 = spark.createDataFrame(departmentsWithEmployeesSeq1)

Я хочу присоединить firstName и lastName внутри массива.

from pyspark.sql import functions as sf
df2 = df1.withColumn("employees.FullName", sf.concat(sf.col('employees.firstName'), sf.col('employees.lastName')))
df2.printSchema()

root
 |-- department: struct (nullable = true)
 |    |-- id: string (nullable = true)
 |    |-- name: string (nullable = true)
 |-- employees: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- firstName: string (nullable = true)
 |    |    |-- lastName: string (nullable = true)
 |    |    |-- email: string (nullable = true)
 |    |    |-- salary: long (nullable = true)
 |-- employees.FullName: array (nullable = true)
 |    |-- element: string (containsNull = true)

Мой новый столбец FullName находится на родительском уровне, как поместить их в массив, например.

root
 |-- department: struct (nullable = true)
 |    |-- id: string (nullable = true)
 |    |-- name: string (nullable = true)
 |-- employees: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- firstName: string (nullable = true)
 |    |    |-- lastName: string (nullable = true)
 |    |    |-- email: string (nullable = true)
 |    |    |-- salary: long (nullable = true)
 |    |    |-- FullName: string (containsNull = true)

1 Ответ

4 голосов
/ 27 мая 2020

Один из способов сделать это - взорвать массив структур ur, используя inline_outer, и использовать concat_ws, чтобы получить свое полное имя и собрать их все, используя array, struct.

from pyspark.sql import functions as F

df1.selectExpr("department","""inline_outer(employees)""")\
   .withColumn("FullName", F.concat_ws(" ","firstName","lastName"))\
   .select("department", F.array(F.struct(*[F.col(x).alias(x) for x in\
                                     ['firstName','lastName','email','salary','FullName']]))\
           .alias("employees")).printSchema()

#root
 #|-- department: struct (nullable = true)
 #|    |-- id: string (nullable = true)
 #|    |-- name: string (nullable = true)
 #|-- employees: array (nullable = false)
 #|    |-- element: struct (containsNull = false)
 #|    |    |-- firstName: string (nullable = true)
 #|    |    |-- lastName: string (nullable = true)
 #|    |    |-- email: string (nullable = true)
 #|    |    |-- salary: long (nullable = true)
 #|    |    |-- FullName: string (nullable = false)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...