如何在Spark DataFrame API中重命名结构数组的元素

时间:2017-07-13 06:19:12

标签: scala apache-spark apache-spark-sql

我有一个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

1 个答案:

答案 0 :(得分:3)

可以转换udf的输出。例如。要将结构域重命名为xy,您可以执行以下操作:

类型安全:

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)