我有一个UDF,它返回一个元组数组:
val df = spark.range(1).toDF("i")
val myUDF = udf((l:Long) => {
Seq((1,2))
})
df.withColumn("udf_result",myUDF($"i"))
.printSchema
给出
root
|-- i: long (nullable = false)
|-- test: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- _1: integer (nullable = false)
| | |-- _2: integer (nullable = false)
我想将结构的元素重命名为有意义的而不是_1
和_2
,如何实现?请注意,我知道返回一个案例类的Seq会让我允许给出正确的字段名称,但是使用带有Yarn的Spark-Notebook(REPL),我们在使用案例类时会遇到很多问题,所以我会这样做。寻找解决方案没有案例类。
我使用Spark 2但使用无类型DataFrames,该解决方案也适用于Spark 1.6
答案 0 :(得分:3)
可以转换udf的输出。例如。要将结构域重命名为x
和y
,您可以执行以下操作:
类型安全:
val schema = ArrayType(
StructType(
Array(
StructField("x",IntegerType),
StructField("y",IntegerType)
)
)
)
df.withColumn("udf_result",myUDF($"i").cast(schema))
或不安全,但使用cast
df.withColumn("udf_result",myUDF($"i").cast("array<struct<x:int,y:int>>"))
两者都会给出架构
root
|-- i: long (nullable = false)
|-- udf_result: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- x: integer (nullable = true)
| | |-- y: integer (nullable = true)