Ata*_*ais 5 scala dataframe apache-spark apache-spark-sql apache-spark-2.0
在我的应用程序中的某个时刻,我有一个带有由案例类创建的Struct字段的DataFrame。现在,我想将其强制转换/映射回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)
Run Code Online (Sandbox Code Playgroud)
基本:
res25.map(r => {
Location(r.getStruct(1).getDouble(0), r.getStruct(1).getDouble(1))
}).show(1)
Run Code Online (Sandbox Code Playgroud)
看起来真的很脏有没有更简单的方法?
在Spark 1.6+中如果你想保留保留的类型信息,那么使用Dataset (DS),而不是DataFrame (DF)。
import spark.implicits._
case class Location(lat: Double, lon: Double)
scala> Seq((10, Location(35, 25)), (20, Location(45, 35))).toDS
res25: org.apache.spark.sql.Dataset[(Int, Location)] = [_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)
Run Code Online (Sandbox Code Playgroud)
它会给你Dataset[(Int, Location)]。现在,如果您想再次回到它的案例类起源,那么只需这样做:
scala> res25.map(r => r._2).show(1)
+----+----+
| lat| lon|
+----+----+
|35.0|25.0|
+----+----+
Run Code Online (Sandbox Code Playgroud)
但是,如果您想坚持使用 DataFrame API,由于它具有动态类型性质,那么您必须像这样编写代码:
scala> res25.select("_2.*").map(r => Location(r.getDouble(0), r.getDouble(1))).show(1)
+----+----+
| lat| lon|
+----+----+
|35.0|25.0|
+----+----+
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7642 次 |
| 最近记录: |