Spark 数据集 - 映射选项 [T] 字段
Spark Dataset - map option[T] fields
我想知道如何处理可为空的数据集列 (Option[T])。
我的目标是使用 spark 数据集 API(例如 "Map")并受益于编译时间类型化的优势。 (我不想使用数据框 API 这样的 "select")
举个例子:我想在列上应用函数。这仅在列不可为空时才有效。
val schema = List(
StructField("name", StringType, false)
, StructField("age", IntegerType, true)
, StructField("children", IntegerType, false)
)
val data = Seq(
Row("miguel", null, 0),
Row("luisa", 21, 1)
)
val df = spark.createDataFrame(
spark.sparkContext.parallelize(data),
StructType(schema)
)
case class Person(name: String, age: Option[Int], children: Int)
// ^
// |
// age is nullable
df.as[Person].map(x => x.children * 12).show
//+-----+
//|value|
//+-----+
//| 0|
//| 12|
//+-----+
df.as[Person].map(x => x.age * 12).show
//<console>:36: error: value * is not a member of Option[Int]
// df.as[Person].map(x => x.age * 12).show
任何人都可以告诉我一个简单的方法来将这个可为 null 的年龄列乘以 12 吗?
谢谢
因为是Option
所以可以直接变形。相反 map
:
df.as[Person].map(x => x.age.map(_ * 12)).show
// +-----+
// |value|
// +-----+
// | null|
// | 252|
// +-----+
实际上我只是 select
:
df.select(($"age" * 12).as[Int]).show
// +----------+
// |(age * 12)|
// +----------+
// | null|
// | 252|
// +----------+
它会表现得更好,当您调用 as[Person]
时,您已经失去了大部分静态类型检查的好处。
我想知道如何处理可为空的数据集列 (Option[T])。 我的目标是使用 spark 数据集 API(例如 "Map")并受益于编译时间类型化的优势。 (我不想使用数据框 API 这样的 "select")
举个例子:我想在列上应用函数。这仅在列不可为空时才有效。
val schema = List(
StructField("name", StringType, false)
, StructField("age", IntegerType, true)
, StructField("children", IntegerType, false)
)
val data = Seq(
Row("miguel", null, 0),
Row("luisa", 21, 1)
)
val df = spark.createDataFrame(
spark.sparkContext.parallelize(data),
StructType(schema)
)
case class Person(name: String, age: Option[Int], children: Int)
// ^
// |
// age is nullable
df.as[Person].map(x => x.children * 12).show
//+-----+
//|value|
//+-----+
//| 0|
//| 12|
//+-----+
df.as[Person].map(x => x.age * 12).show
//<console>:36: error: value * is not a member of Option[Int]
// df.as[Person].map(x => x.age * 12).show
任何人都可以告诉我一个简单的方法来将这个可为 null 的年龄列乘以 12 吗?
谢谢
因为是Option
所以可以直接变形。相反 map
:
df.as[Person].map(x => x.age.map(_ * 12)).show
// +-----+
// |value|
// +-----+
// | null|
// | 252|
// +-----+
实际上我只是 select
:
df.select(($"age" * 12).as[Int]).show
// +----------+
// |(age * 12)|
// +----------+
// | null|
// | 252|
// +----------+
它会表现得更好,当您调用 as[Person]
时,您已经失去了大部分静态类型检查的好处。