如何有效地重命名数据集中的列(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()
使用 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()