У меня есть искровой фрейм со следующим форматом, который нужно разбить.Я проверяю другие решения, такие как это .Однако в моем случае before
и after
могут быть массивами разной длины.
root
|-- id: string (nullable = true)
|-- before: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- start_time: string (nullable = true)
| | |-- end_time: string (nullable = true)
| | |-- area: string (nullable = true)
|-- after: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- start_time: string (nullable = true)
| | |-- end_time: string (nullable = true)
| | |-- area: string (nullable = true)
Например, если фрейм данных имеет только одну строку, before
- это массив размера 2, а after
- это массив размера 3, в разобранной версии должно быть 5 строк сследующая схема:
root
|-- id: string (nullable = true)
|-- type: string (nullable = true)
|-- start_time: integer (nullable = false)
|-- end_time: string (nullable = true)
|-- area: string (nullable = true)
, где type
- это новый столбец, который может быть "before"
или "после" .
Я могу сделать это в двух отдельных взрывах, где я делаю столбец type
в каждом взрыве и затем union
.
val dfSummary1 = df.withColumn("before_exp",
explode($"before")).withColumn("type",
lit("before")).withColumn(
"start_time", $"before_exp.start_time").withColumn(
"end_time", $"before_exp.end_time").withColumn(
"area", $"before_exp.area").drop("before_exp", "before")
val dfSummary2 = df.withColumn("after_exp",
explode($"after")).withColumn("type",
lit("after")).withColumn(
"start_time", $"after_exp.start_time").withColumn(
"end_time", $"after_exp.end_time").withColumn(
"area", $"after_exp.area").drop("after_exp", "after")
val dfResult = dfSumamry1.unionAll(dfSummary2)
Но мне было интересно, есть ли более элегантный способ сделать это.Спасибо.