2017-01-18 3 views
1

Когда я пытался преобразовать DataFrame искру в в РДД [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 

Это сработало отлично.

В то время как первый метод был введен в official version of Spark-2.2.0-SNAPSHOT при преобразовании строки в массив [Двойной], он не работает.

Может ли кто-нибудь выяснить причину?

ответ

2

Эти два метода не делают то же самое. В первом случае вы пытаетесь сопоставлять с одним столбцом 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], которая дает вам последовательность значений полей.

Смежные вопросы