如何有效地重命名数据集中的列(Spark 2.0)

How to efficiently rename columns in Datasets (Spark 2.0)

使用 DataFrame,只需使用 df.withColumnRename("oldName", "newName") 重命名列即可。在 Datasets 中,由于每个字段都是类型化和命名的,这似乎是不可能的。我能想到的唯一解决方法是在数据集上使用 map

case class Orig(a: Int, b: Int)
case class OrigRenamed(a: Int, bNewName: Int)

val origDS = Seq(Orig(1,2), Orig(3,4)).toDS
origDS.show
+---+---+
|  a|  b|
+---+---+
|  1|  2|
|  3|  4|
+---+---+

// To rename with map
val origRenamedDS = origDS.map{ case Orig(x,y) => OrigRenamed(x,y) }
origRenamed.show
+---+--------+
|  a|bNewName|
+---+--------+
|  1|       2|
|  3|       4|
+---+--------+

这似乎是一种非常迂回且低效的方法,只是重命名列。有没有更好的方法?

一个稍微更简洁的解决方案是这样的:

origDS.toDF("a", "bNewName").as[OrigRenamed]

但实际上重命名对静态类型 Dataset 根本没有意义。虽然我们使用与 Dataframe (Dataset[Row]) 相同的柱状表示,但这里的语义完全不同。

列的名称对应于存储对象的特定字段,因此不能动态重命名。换句话说 Datasets 不是静态类型 DataFrames 而是对象的集合。

您可以使其稍微简洁一些,同时保持语义:

origDS.map(o => OrigRenamed(o.a, o.b)).show()