使用Scala在Spark中将org.apache.spark.mllib.linalg.Vector RDD转换为DataFrame

4

我有一个 org.apache.spark.mllib.linalg.Vector RDD,其中包含 [Int Int Int] 类型的数据。 我尝试使用以下代码将其转换为 dataframe:

import sqlContext.implicits._
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.DataTypes
import org.apache.spark.sql.types.ArrayData
属于类型org.apache.spark.mllib.linalg.Vector。
val vectarr = vectrdd.toArray()
case class RFM(Recency: Integer, Frequency: Integer, Monetary: Integer)
val df = vectarr.map { case Array(p0, p1, p2) => RFM(p0, p1, p2) }.toDF()

我遇到了以下错误。
warning: fruitless type test: a value of type         
org.apache.spark.mllib.linalg.Vector cannot also be a Array[T]
val df = vectarr.map { case Array(p0, p1, p2) => RFM(p0, p1, p2) }.toDF()

error: pattern type is incompatible with expected type;
found   : Array[T]
required: org.apache.spark.mllib.linalg.Vector
val df = vectarr.map { case Array(p0, p1, p2) => RFM(p0, p1, p2) }.toDF()

我尝试的第二种方法是这样的:
val vectarr=vectrdd.toArray().take(2)
case class RFM(Recency: String, Frequency: String, Monetary: String)
val df = vectrdd.map { case (t0, t1, t2) => RFM(p0, p1, p2) }.toDF()

我遇到了这个错误。
error: constructor cannot be instantiated to expected type;
found   : (T1, T2, T3)
required: org.apache.spark.mllib.linalg.Vector
val df = vectrdd.map { case (t0, t1, t2) => RFM(p0, p1, p2) }.toDF()

我使用这个示例作为指南 >> 在Spark/Scala中将RDD转换为DataFrame

1个回答

3
的类型为Array[org.apache.spark.mllib.linalg.Vector],因此在模式匹配中不能匹配Array(p0, p1, p2),因为要匹配的是矢量而不是数组。

此外,您不应该执行val vectarr = vectrdd.toArray() - 这会将RDD转换为数组,然后对toDF的最终调用将无法工作,因为toDF仅适用于RDD。

正确的行应该是(提供您将RFM更改为Doubles)

val df = vectrdd.map(_.toArray).map { case Array(p0, p1, p2) => RFM(p0, p1, p2)}.toDF()

或者,等价地替换 val vectarr = vectrdd.toArray()(生成Array[Vector])与 val arrayRDD = vectrdd.map(_.toArray())(生成RDD[Array[Double]]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接