Вот одно решение, основанное на встроенных функциях Spark:
import org.apache.spark.sql.functions.{monotonically_increasing_id, explode, first}
val df = Seq(
(Map("key1" -> "value1", "key2" -> "value2", "key3" -> "value3", "key4" -> "value4")),
(Map("key1" -> "value1", "key2" -> "value2")),
(Map("key1" -> "value1", "key3" -> "value3")))
.toDF("map_data")
df.withColumn("id", monotonically_increasing_id)
.select($"id", explode($"map_data"))
.groupBy("id")
.pivot("key")
.agg(first("value"))
.show(false)
// +---+------+------+------+------+
// |id |key1 |key2 |key3 |key4 |
// +---+------+------+------+------+
// |0 |value1|value2|value3|value4|
// |1 |value1|value2|null |null |
// |2 |value1|null |value3|null |
// +---+------+------+------+------+
Объяснение
withColumn("id", monotonically_increasing_id)
: добавить уникальный идентификатор для каждой строки. explode($"map_data")
: развернуть map_data
, это создаст два дополнительных столбца, key
и value
. groupBy...pivot
: сгруппировать по идентификатору и сводным значениям для ключей