如何就地修改数据框,使其ArrayType列不能为nullnullable = false和containsNull = false?

问题描述

采用以下示例数据框:

val df = Seq(Seq("xxx")).toDF("a")

模式:

root
 |-- a: array (nullable = true)
 |    |-- element: string (containsNull = true)

如何就地修改df,以使结果数据框在任何地方都不能为空,即具有以下架构:

root
 |-- a: array (nullable = false)
 |    |-- element: string (containsNull = false)

我了解我可以重新创建一个强制执行不可空模式的数据框,例如遵循Change nullable property of column in spark dataframe

spark.createDataFrame(df.rdd,StructType(StructField("a",ArrayType(StringType,false),false) :: Nil))

但这不是结构化流中的选项,因此我希望它是某种就地修改。

解决方法

因此,实现这一目标的方法是使用UserDefinedFunction

// Problem setup
val df = Seq(Seq("xxx")).toDF("a")

df.printSchema
root
|-- a: array (nullable = true)
|    |-- element: string (containsNull = true)

解决方案:

import org.apache.spark.sql.types.{ArrayType,StringType}
import org.apache.spark.sql.functions.{udf,col}

// We define a sub schema with the appropriate data type and null condition
val subSchema = ArrayType(StringType,containsNull = false)

// We create a UDF that applies this sub schema
// while specifying the output of the UDF to be non-nullable
val applyNonNullableSchemaUdf =  udf((x:Seq[String]) => x,subSchema).asNonNullable

// We apply the UDF
val newSchemaDF = df.withColumn("a",applyNonNullableSchemaUdf(col("a")))

就在那里。

// Check new schema
newSchemaDF.printSchema
root
|-- a: array (nullable = false)
|    |-- element: string (containsNull = false)

// Check that it actually works
newSchemaDF.show
+-----+
|    a|
+-----+
|[xxx]|
+-----+

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...