Как создать набор данных (не 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. как разработчика 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]
, так что это не совсем дает тот же результат.
См. этот пост для получения дополнительной информации о том, как создавать наборы данных.