首页 > 解决方案 > 火花数据帧行上的映射函数以解析结构类型

问题描述

我有一个使用以下内容构建的 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()

标签: apache-sparkapache-spark-sql

解决方案


您可以使用点访问嵌套列的值:

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 调用是优化器的“黑匣子”。

可以在此处找到这些访问方法的更多示例。


推荐阅读