Как создать набор данных (не DataFrame) без использования case-класса, но с использованием StructType?

Как я могу создать набор данных, используя StructType?

Мы можем создать Dataset следующее:

case class Person(name: String, age: Int)

val personDS = Seq(Person("Max", 33), Person("Adam", 32), Person("Muller", 
62)).toDS()
personDS.show()

Есть ли способ создать Dataset без использования кейс-класса?

Я хотел бы создать DataFrame используя класс case и используя StructType,

3 ответа

Если вы знаете, как создать DataFrame, вы уже сейчас знаете, как создать Dataset:)

DataFrame = Dataset[Row].

Что это означает? Пытаться:

val df : DataFrame = spark.createDataFrame(...) // with StructType
import org.apache.spark.sql._
val ds : Dataset[Row] = df; // no error, as DataFrame is only a type alias of Dataset[Row]

Это интересный вопрос в том смысле, что я не вижу причин, почему бы этого захотеть.

Как я могу создать набор данных с помощью "StructType"

Я бы тогда задал очень похожий вопрос...

Почему вы хотели бы "обменять" класс дел на StructType? Что бы это дало вам, что кейс-класс не мог?

Причина использования класса case заключается в том, что он может предложить вам две вещи одновременно:

  1. Опишите свою схему быстро, красиво и безопасно для типов

  2. Работа с вашими данными становится безопасной для типов

Что касается 1. как разработчика Scala, вы будете определять бизнес-объекты, которые описывают ваши данные. Вам все равно придется это делать (если вы не любите кортежи и _1 и тому подобное).

Относительно безопасности типов (как в 1., так и в 2.) речь идет о преобразовании ваших данных для использования компилятора Scala, который может помочь найти места, где вы ожидаете String, но имеете Int. С StructType проверка только во время выполнения (не во время компиляции).

С учетом всего сказанного, ответ на ваш вопрос "да".

Вы можете создать набор данных, используя StructType,

scala> val personDS = Seq(("Max", 33), ("Adam", 32), ("Muller", 62)).toDS
personDS: org.apache.spark.sql.Dataset[(String, Int)] = [_1: string, _2: int]

scala> personDS.show
+------+---+
|    _1| _2|
+------+---+
|   Max| 33|
|  Adam| 32|
|Muller| 62|
+------+---+

Вы можете быть удивлены, почему я не вижу названия столбцов. Это как раз и есть причина для класса case, который будет не только давать вам типы, но и имена столбцов.

Однако есть один трюк, который можно использовать, чтобы избежать работы с классами case, если они вам не нравятся.

val withNames = personDS.toDF("name", "age").as[(String, Int)]
scala> withNames.show
+------+---+
|  name|age|
+------+---+
|   Max| 33|
|  Adam| 32|
|Muller| 62|
+------+---+

Вот как вы можете создать набор данных с помощью StructType:

      import org.apache.spark.sql.types._
import org.apache.spark.sql.Row

val schema = StructType(Seq(
  StructField("name", StringType, true),
  StructField("age", IntegerType, true)
))

val data = Seq(
  Row("Max", 33),
  Row("Adam", 32),
  Row("Muller", 62)
)

val personDF = spark.createDataFrame(
  spark.sparkContext.parallelize(data),
  schema
)

val yourDS = personDF.as[(String, Int)]

yourDS.show()
      +------+---+
|  name|age|
+------+---+
|   Max| 33|
|  Adam| 32|
|Muller| 62|
+------+---+

yourDSэто org.apache.spark.sql.Dataset[(String, Int)].

The personDSв вашем вопросе типа org.apache.spark.sql.Dataset[Person], так что это не совсем дает тот же результат.

См. этот пост для получения дополнительной информации о том, как создавать наборы данных.

Другие вопросы по тегам