apache-spark - 火花数据帧行上的映射函数以解析结构类型
问题描述
我有一个使用以下内容构建的 spark 数据框:
val empData = Seq(
Row("1", "s1", Row("f1", "l1")),
Row("2", "s2", Row("f2", "l2")),
Row("3", "s3", null)
)
val empSchema = new StructType()
.add("emp_id", StringType, true)
.add("emp_state", StringType, true)
.add("emp_name", new StructType()
.add("firstname", StringType, true)
.add("lastname", StringType, true),
true)
val empDF = spark.createDataFrame(spark.sparkContext.parallelize(empData), empSchema)
我正在尝试将数据框中的每一行替换为 emp_name 的名字(emp_name 的类型为 struct)。下面的代码有什么问题?:
def mapDFRowsUsingRowOperator_getSeq_forStructType(df: DataFrame) = {
df.map(r => { r.getAs[Row]("emp_name").getAs[String]("firstname") } )
}
我看到错误:
Unable to find encoder for type org.apache.spark.sql.Row.
我们也可以在这个用例中使用 getStruct()
解决方案
您可以使用点访问嵌套列的值:
empDF.select("emp_id", "emp_state", "emp_name.firstname", "emp_name.lastname").show()
印刷
+------+---------+---------+--------+
|emp_id|emp_state|firstname|lastname|
+------+---------+---------+--------+
| 1| s1| f1| l1|
| 2| s2| f2| l2|
| 3| s3| null| null|
+------+---------+---------+--------+
这是访问结构元素的更简单方法,并且需要更少的代码。此外,您可能会获得性能改进,因为这些表达式可以由 Catalyst 优化器解析,而 map 调用是优化器的“黑匣子”。
可以在此处找到这些访问方法的更多示例。