WrappedArray到Dataframe的Spark Dataframe [Vector]

时间:2017-05-18 15:09:13

标签: scala apache-spark spark-dataframe

我有一个带有以下架构的火花Dataframe df

root
 |-- features: array (nullable = true)
 |    |-- element: double (containsNull = false)

我想创建一个新的Dataframe,其中每一行都是Double的Vector,并期望得到以下架构:

root
     |-- features: vector (nullable = true)

到目前为止,我有以下代码(受到这篇文章的影响:Converting Spark Dataframe(with WrappedArray) to RDD[labelPoint] in scala)但是我担心它有问题,因为计算甚至合理的行数需要很长时间。 此外,如果行太多,应用程序将因堆空间异常而崩溃。

val clustSet = df.rdd.map(r => {
          val arr = r.getAs[mutable.WrappedArray[Double]]("features")
          val features: Vector = Vectors.dense(arr.toArray)
          features
          }).map(Tuple1(_)).toDF()

我怀疑在这种情况下,arr.toArray指令不是一个好的Spark练习。任何澄清都会非常有用。

谢谢!

1 个答案:

答案 0 :(得分:4)

这是因为.rdd必须从内部内存格式中反序列化对象,这非常耗时。

可以使用.toArray - 您在行级别上操作,而不是将所有内容收集到驱动程序节点。

您可以使用UDF轻松完成此操作:

import org.apache.spark.ml.linalg._
val convertUDF = udf((array : Seq[Double]) => {
  Vectors.dense(array.toArray)
})
val withVector = dataset
  .withColumn("features", convertUDF('features))

代码来自这个答案:Convert ArrayType(FloatType,false) to VectorUTD

然而,该问题的作者没有询问差异