Фреймы данных динамически типизированы, а наборы данных и RDD - статически. Это означает, что когда вы определяете набор данных или RDD, вам нужно явно указать класс, который представляет контент. Это может быть полезно, потому что когда вы пишете преобразования в ваш набор данных, компилятор может проверить ваш код на безопасность типов. Возьмите, например, этот набор данных о питомцах. Когда я использую pet.species
или pet.name
, компилятор знает их типы во время компиляции.
case class Pet(name: String, species: String, age: Int, weight: Double)
val data: Dataset[Pet] = Seq(
Pet("spot", "dog", 2, 50.5),
Pet("mittens", "cat", 11, 15.5),
Pet("mickey", "mouse", 1, 1.5)).toDS
println(data.map(x => x.getClass.getSimpleName).first)
// Pet
val newDataset: Dataset[String] = data.map(pet => s"I have a ${pet.species} named ${pet.name}.")
Когда мы переключаемся на использование DataFrame, схема остается прежней, и данные по-прежнему набираются (или структурируются), но эта информация доступна только во время выполнения. Это называется динамическая типизация. Это препятствует тому, чтобы компилятор ловил ваши ошибки, но это может быть очень полезно, потому что позволяет вам писать SQL-подобные операторы и определять новые столбцы на лету, например, добавляя столбцы к существующему DataFrame, без необходимости определять новый класс для каждого маленькая операция. С другой стороны, вы можете определить неправильные операции, которые приводят к нулям или в некоторых случаях к ошибкам во время выполнения.
val df: DataFrame = data.toDF
df.printSchema()
// root
// |-- name: string (nullable = true)
// |-- species: string (nullable = true)
// |-- age: integer (nullable = false)
// |-- weight: double (nullable = false)
val newDf: DataFrame = df
.withColumn("some column", ($"age" + $"weight"))
.withColumn("bad column", ($"name" + $"age"))
newDf.show()
// +-------+-------+---+------+-----------+----------+
// | name|species|age|weight|some column|bad column|
// +-------+-------+---+------+-----------+----------+
// | spot| dog| 2| 50.5| 52.5| null|
// |mittens| cat| 11| 15.5| 26.5| null|
// | mickey| mouse| 1| 1.5| 2.5| null|
// +-------+-------+---+------+-----------+----------+