使用Spark Dataframe Scala将Array [Double]列转换为字符串或两个不同的列

时间:2015-08-23 11:40:44

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

我之前遇到了障碍,试图在Spark Dataframes中进行一些转换。

假设我有一个架构的数据框:

root
|-- coordinates: array (nullable = true)
|    |-- element: double (containsNull = true)
|-- userid: string (nullable = true)
|-- pubuid: string (nullable = true)

我想摆脱坐标中的数组(double),而是获得一个看起来像

的行的DF
"coordinates(0),coordinates(1)", userid, pubuid 
                   or something like 
 coordinates(0), coordinates(1), userid, pubuid . 

使用Scala,我可以做到

coordinates.mkString(",")

但在DataFrames中,坐标解析为java.util.List。

到目前为止,我通过阅读RDD,转换然后构建新的DF来解决这个问题。但我想知道是否有更优雅的方法来使用Dataframes。

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

您可以使用UDF:

import org.apache.spark.sql.functions.{udf, lit}

val mkString = udf((a: Seq[Double]) => a.mkString(", "))
df.withColumn("coordinates_string", mkString($"coordinates"))

val apply = udf((a: Seq[Double], i: Int) => a(i))
df.select(
  $"*", 
  apply($"coordinates", lit(0)).alias("x"),
  apply($"coordinates", lit(1)).alias("y")
)

修改

在最近的版本中,您还可以使用concat_ws

import org.apache.spark.sql.functions.concat_ws

df.withColumn(
  "coordinates_string", concat_ws(",", $"coordinates")
)

或简单Column.apply

df.select($"*", $"coordinates"(0).alias("x"), $"coordinates"(1).alias("y"))