在Spark中创建给定模式的空数组列

Rap*_*oth 10 scala apache-spark

由于镶木地板解析空数组的事实,我在写表之前将空数组替换为null.现在,当我阅读表格时,我想做相反的事情:

我有一个具有以下架构的DataFrame:

|-- id: long (nullable = false)
 |-- arr: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- x: double (nullable = true)
 |    |    |-- y: double (nullable = true)
Run Code Online (Sandbox Code Playgroud)

以及以下内容:

+---+-----------+
| id|        arr|
+---+-----------+
|  1|[[1.0,2.0]]|
|  2|       null|
+---+-----------+
Run Code Online (Sandbox Code Playgroud)

我想用空数组替换null数组(id = 2),即

+---+-----------+
| id|        arr|
+---+-----------+
|  1|[[1.0,2.0]]|
|  2|         []|
+---+-----------+
Run Code Online (Sandbox Code Playgroud)

我试过了:

val arrSchema = df.schema(1).dataType

df
.withColumn("arr",when($"arr".isNull,array().cast(arrSchema)).otherwise($"arr"))
.show()
Run Code Online (Sandbox Code Playgroud)

这使 :

java.lang.ClassCastException:org.apache.spark.sql.types.NullType $无法强制转换为org.apache.spark.sql.types.StructType

编辑:我不想"硬编码"我的数组列的任何模式(至少不是结构的模式),因为这可能因情况而异.我只能df在运行时使用架构信息

我顺便使用Spark 2.1,因此我无法使用 typedLit

hi-*_*zir 7


Rap*_*oth 2

一种方法是使用 UDF :

val arrSchema = df.schema(1).dataType // ArrayType(StructType(StructField(x,DoubleType,true), StructField(y,DoubleType,true)),true)

val emptyArr = udf(() => Seq.empty[Any],arrSchema)

df
.withColumn("arr",when($"arr".isNull,emptyArr()).otherwise($"arr"))
.show()

+---+-----------+
| id|        arr|
+---+-----------+
|  1|[[1.0,2.0]]|
|  2|         []|
+---+-----------+
Run Code Online (Sandbox Code Playgroud)