Следуя принятому ответу, когда элементы массива являются сложным типом, его трудно определить вручную (например, с большими структурами).
Чтобы сделать это автоматически, я написал следующий помощник метод:
def explodeOuter(df: Dataset[Row], columnsToExplode: List[String]) = {
val arrayFields = df.schema.fields
.map(field => field.name -> field.dataType)
.collect { case (name: String, type: ArrayType) => (name, type.asInstanceOf[ArrayType])}
.toMap
columnsToExplode.foldLeft(df) { (dataFrame, arrayCol) =>
dataFrame.withColumn(arrayCol, explode(when(size(col(arrayCol)) =!= 0, col(arrayCol))
.otherwise(array(lit(null).cast(arrayFields(arrayCol).elementType)))))
}
Обнаружено, что существует проблема, созданная в проекте protobuf: https://github.com/gogo/protobuf/issues/433 , поэтому подтверждено, что в настоящее время нет другого пути.