Mapspark dataframe行上的函数以解析结构类型

t98cgbkg  于 2021-05-29  发布在  Spark
关注(0)|答案(2)|浏览(355)

我有一个sparkDataframe,它使用:

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\u name的firstname(emp\u name是struct类型)替换Dataframe中的每一行。下面的代码有什么问题

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()

g6baxovj

g6baxovj1#

更改以下功能

def mapDFRowsUsingRowOperator_getSeq_forStructType(df: DataFrame) = {
   df.map(r => { r.getAs[Row]("emp_name").getAs[String]("firstname") } )
}

def mapDFRowsUsingRowOperator_getSeq_forStructType(df: DataFrame) = {   
   df
     .map(r => {
           if(r.getStruct(2) != null) 
              r.getStruct(2).getAs[String](0) 
           else 
              "" // You can change this null if you want to display null in column value.
        })
     .withColumnRenamed("value","firstname")
}
kxeu7u2r

kxeu7u2r2#

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

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调用是优化器的“黑盒”。
这些访问方法的更多示例可以在这里找到。

相关问题