2017-09-02 63 views
1

尝试在Apache Spark和Scala中创建特征矢量中所有特征的数组。我需要这样做,以便为算法中的各种流量创建Breeze矩阵。目前这些功能都包含在一个特征向量中,我想分别提取这些特征。我一直在寻找以下问题: Applying IndexToString to features vector in Spark从Apache Spark/Scala中的特征矢量创建数组

这里是我当前的代码:(数据为Spark数据框,所有的功能都双打)

val featureCols = Array("feature1", "feature2", "feature3") 
val featureAssembler = new VectorAssembler().setInputCols(featureCols).setOutputCol("features") 
val dataWithFeatures = featureAssembler.transform(data) 

//now we slice the features back again 
val featureSlicer = featureCols.map { 
    col => new VectorSlicer().setInputCol("features").setOutputCol(s"${col}_sliced").setNames(Array(s"${col}"))} 
val output = featureSlicer.map(f => f.transform(dataWithFeatures).select(f.getOutputCol).as[Double].collect) 
val array = output.flatten.toArray 

但是这个失败,出现以下错误:“不能解决CAST(“特征1”双倍由于数据类型不匹配 - 不能施放VectorUDT到DoubleType”

这似乎奇怪,因为我可以做的没有一个错误如下:

val array: Array[Double] = dataWithFeatures.select("feature1").as[Double].collect()

任何想法如何解决这个问题,以及是否有更好的方法,因为创建一系列DataFrame并分别对每个DataFrame执行操作似乎效率低下。

谢谢!

+0

你需要什么的结果呢? '数组[数组[双]]'? – Psidom

+0

理想情况下只是数组[双]。作为BreezeDM的基础,只是一系列值。但我可以压扁阵列[数组[双]]如果有必要我猜? – LucieCBurgess

回答

0

说,如果features列是会从所有其他功能列组装vector列,您可以选择features列,将其转换为rdd,然后flatMap它:

示例数据

dataWithFeatures.show 
+--------+--------+--------+-------------+ 
|feature1|feature2|feature3|  features| 
+--------+--------+--------+-------------+ 
|  1|  2|  3|[1.0,2.0,3.0]| 
|  4|  5|  6|[4.0,5.0,6.0]| 
+--------+--------+--------+-------------+ 

import org.apache.spark.ml.linalg.Vector 

dataWithFeatures.select("features").rdd.flatMap(r => r.getAs[Vector](0).toArray).collect 
// res19: Array[Double] = Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0) 
+0

哇!这太神奇了 - 非常快,非常整洁 - 我一直在摔跤了四个小时!谢谢! – LucieCBurgess

+0

PS。你如何在答案中设置你的表格? – LucieCBurgess

+0

你的意思是*示例数据*?您可以通过选择表格然后编辑 - >'{}'来简单地将其格式化为代码。 – Psidom