Как мне преобразовать RDD из org.apache.spark.ml.linalg.Vector в набор данных? - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь понять, как работает преобразование между RDD, DataSets и DataFrames.Я довольно новичок в Spark, и я застреваю каждый раз, когда мне нужно перейти от модели данных к другой (особенно от RDD к наборам данных и фреймам данных).Может ли кто-нибудь объяснить мне правильный способ сделать это?

В качестве примера, теперь у меня есть RDD[org.apache.spark.ml.linalg.Vector], и мне нужно передать его в мой алгоритм машинного обучения, например, KMeans (Spark DataSet MLlib).Итак, мне нужно преобразовать его в набор данных с одним столбцом с именем «features», который должен содержать строки типа Vector.Как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Все, что вам нужно, это Encoder.Импорт

import org.apache.spark.sql.Encoder
import org.apache.spark.sql.catalyst.encoders.ExpressionEncoder
import org.apache.spark.ml.linalg

RDD:

val rdd = sc.parallelize(Seq(
  linalg.Vectors.dense(1.0, 2.0), linalg.Vectors.sparse(2, Array(), Array())
))

Преобразование:

val ds = spark.createDataset(rdd)(ExpressionEncoder(): Encoder[linalg.Vector])
 .toDF("features")

ds.show
// +---------+
// | features|
// +---------+
// |[1.0,2.0]|
// |(2,[],[])|
// +---------+


ds.printSchema
// root
//  |-- features: vector (nullable = true)
0 голосов
/ 05 июня 2018

Чтобы преобразовать СДР в фрейм данных , проще всего использовать toDF() в Scala.Чтобы использовать эту функцию, необходимо импортировать имплики, которые выполняются с использованием объекта SparkSession.Это можно сделать следующим образом:

val spark = SparkSession.builder().getOrCreate()
import spark.implicits._

val df = rdd.toDF("features")

toDF() принимает СДР из кортежей.Когда СДР состоит из общих объектов Scala, они будут неявно преобразованы, то есть нет необходимости делать что-либо, а когда СДР имеет несколько столбцов, нет необходимости также что-либо делать, СДР уже содержит кортеж.Однако в этом особом случае вам необходимо сначала преобразовать RDD[org.apache.spark.ml.linalg.Vector] в RDD[(org.apache.spark.ml.linalg.Vector)].Поэтому необходимо выполнить преобразование в кортеж следующим образом:

val df = rdd.map(Tuple1(_)).toDF("features")

Выше приведено преобразование СДР в кадр данных с одним столбцом, называемым функциями.


Для преобразованиядля набора данных самый простой способ - использовать класс case.Убедитесь, что класс case определен вне объекта Main.Сначала преобразуйте СДР в кадр данных, затем выполните следующие действия:

case class A(features: org.apache.spark.ml.linalg.Vector)

val ds = df.as[A]

Чтобы показать все возможные преобразования, получить доступ к базовому СДР из кадра данных или набора данных можно с помощью .rdd:

val rdd = df.rdd

Вместо преобразования назад и вперед между RDD и наборами данных / наборами данных, как правило, легче выполнять все вычисления с использованием API-интерфейса dataframe.Если нет подходящей функции для выполнения того, что вы хотите, обычно можно определить UDF, определяемую пользователем функцию.Смотрите, например, здесь: https://jaceklaskowski.gitbooks.io/mastering-spark-sql/spark-sql-udfs.html

...