Коли я намагався перетворити Іскра 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
Це спрацювало добре.
Поки перший метод був введений в офіційна версія Spark-2.2.0-SNAPSHOT при конвертації рядок в Масив [подвійний], це не спрацювало.
Чи може хто-небудь зрозуміти причину?
Відповіді:
2 для відповіді № 1Ці два способи не роблять те ж саме. У першому випадку ви намагаєтеся зіставити з a 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]
яка дає вам послідовність значень поля.