当我尝试使用以下代码将Spark的DataFrame
转换为RDD[org.apache.spark.mllib.linalg.Vector]
时:
import org.apache.spark.sql.Row
import org.apache.spark.mllib.linalg.Vectors
val df = sqlContext.createDataFrame(
Seq((0.1, 0.2, 0.4))
).toDF("t1", "t2", "t3")
df.rdd.map{ case Row(row: Seq[_]) =>
Vectors.dense(row.asInstanceOf[Seq[Double]].toArray)
}.collect
我收到如下错误消息:
scala.MatchError: [0.1,0.2,0.4] (of class org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema)
然后我尝试了另一种方法:
df.content.rdd.map{ case row =>
Vectors.dense(row.toSeq.toArray.map{
x => x.asInstanceOf[Double]
})
}.collect
结果很好。
虽然在将row
转换为Array[Double]
时在official version of Spark-2.2.0-SNAPSHOT中引入了第一种方法,但它无效。
有人能找出原因吗?
答案 0 :(得分:2)
这两种方法不做同样的事情。在第一种情况下,您尝试使用单个Row
列与ArrayType
进行匹配。由于您的输入包含三列,因此MatchException
是预期结果。仅当您将列作为数组收集时,这才有效,例如
df.select(array(df.columns.map(col(_)): _*)).rdd.map {
case Row(xs: Seq[Double @unchecked]) => xs
}
或
df.select(array(df.columns.map(col(_)): _*)).rdd.map(_.getSeq[Double](0))
在第二种情况下,您要将行转换为Seq[Any]
,它会为您提供一系列字段值。