scala – 如何将DataFrame中的struct映射到case类?

前端之家收集整理的这篇文章主要介绍了scala – 如何将DataFrame中的struct映射到case类?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我的应用程序中的某个时刻,我有一个DataFrame,其中包含从案例类创建的Struct字段.现在我想将它转换/映射回case类类型:

import spark.implicits._
case class Location(lat: Double,lon: Double)

scala> Seq((10,Location(35,25)),(20,Location(45,35))).toDF
res25: org.apache.spark.sql.DataFrame = [_1: int,_2: struct<lat: double,lon: double>]

scala> res25.printSchema
root
 |-- _1: integer (nullable = false)
 |-- _2: struct (nullable = true)
 |    |-- lat: double (nullable = false)
 |    |-- lon: double (nullable = false)

基本的:

res25.map(r => {
   Location(r.getStruct(1).getDouble(0),r.getStruct(1).getDouble(1))
}).show(1)

看起来很脏
有没有更简单的方法

解决方法

在Spark 1.6中,如果要保留保留的类型信息,请使用数据集(DS),而不是DataFrame(DF).

import spark.implicits._
case class Location(lat: Double,35))).toDS
res25: org.apache.spark.sql.Dataset[(Int,Location)] = [_1: int,lon: double>]

scala> res25.printSchema
root
 |-- _1: integer (nullable = false)
 |-- _2: struct (nullable = true)
 |    |-- lat: double (nullable = false)
 |    |-- lon: double (nullable = false)

它会给你数据集[(Int,Location)].现在,如果你想再次回到它的case类原点,那么就这样做:

scala> res25.map(r => r._2).show(1)
+----+----+
| lat| lon|
+----+----+
|35.0|25.0|
+----+----+

但是,如果你想坚持DataFrame API,因为它是动态类型的性质,那么你必须像这样编码它:

scala> res25.select("_2.*").map(r => Location(r.getDouble(0),r.getDouble(1))).show(1)
+----+----+
| lat| lon|
+----+----+
|35.0|25.0|
+----+----+

猜你在找的Scala相关文章