如何就地修改数据框,使其 ArrayType 列不能为空(nullable = false 且 containsNull = false)?

Posted

技术标签:

【中文标题】如何就地修改数据框,使其 ArrayType 列不能为空(nullable = false 且 containsNull = false)?【英文标题】:How to modify a dataframe in-place so that its ArrayType column can't be null (nullable = false and containsNull = false)? 【发布时间】:2020-08-21 07:25:13 【问题描述】:

以以下示例数据框为例:

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))

但这不是结构化流下的选项,所以我希望它是某种就地修改。

【问题讨论】:

这能回答你的问题吗? Change nullable property of column in spark dataframe 那么当您尝试将具有空元素的数组转换为 DataFrame 时,您希望发生什么? @Lamanus 如果我理解正确,那么该问题下的答案并不能解决我的情况。正如我在问题描述中提到的,createDataFrame 在结构化流中是不可能的。您是否建议在 foreachBatch 接收器中为每个微批量数据帧重新创建数据帧? @kfkhalili 我可以确保所有空元素都已从数据帧转换的前一阶段过滤掉。 【参考方案1】:

所以实现这一点的方法是使用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]|
+-----+

【讨论】:

以上是关于如何就地修改数据框,使其 ArrayType 列不能为空(nullable = false 且 containsNull = false)?的主要内容,如果未能解决你的问题,请参考以下文章

在pyspark中创建带有arraytype列的数据框

从 Spark 数据框列中 ArrayType 类型的行中获取不同的元素

如何在组合框中就地更改显示字段

如何修改 Spark 数据框中的 numpy 数组?

是否可以使用Crealytics spark-excel软件包将具有ArrayType列的Spark数据框写入Excel?

spark中混合数据的ArrayType