我有一个带有以下架构的火花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练习。任何澄清都会非常有用。
谢谢!
答案 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
然而,该问题的作者没有询问差异