【问题标题】:Using a Map to rename and select columns on an Apache Spark Dataframe (Scala) [duplicate]使用地图重命名和选择 Apache Spark 数据框(Scala)上的列 [重复]
【发布时间】:2019-03-29 02:42:36
【问题描述】:

从数据框开始:

val someDF = Seq(
  (8, "bat", "h"),
  (64, "mouse", "t"),
  (-27, "horse", "x")
).toDF("number", "thing", "letter")

someDF.show()

+------+-----+------+
|number|thing|letter|
+------+-----+------+
|     8|  bat|     h|
|    64|mouse|     t|
|   -27|horse|     x|
+------+-----+------+

还有一个Map

val lookup = Map(
  "number" -> "id",
  "thing" -> "animal"
)

我想选择并重命名列,使 number 变为 id thing 变成 animal 等等。

另一个 Stack Overflow 问题涉及重命名:Renaming column names of a DataFrame in Spark Scala,我确信有一种直接的方法可以在我没有看到的同时进行选择。

我认为沿着这些思路的东西会起作用,但是尽管输入是字符串并且它使用 Seq 而不是映射,但还是会出现很多类型不匹配:

val renamed_selected = someDF.select(
      lookup.map(m => col(m._1).as(m._2))
    ):_*

所以想要的输出是:

+------+------+
|id    |animal|
+------+------+
|     8|  bat |     
|    64|mouse |     
|   -27|horse |     
+------+------+

谢谢?????????

关于重复问题标志的说明:问题Renaming column names of a DataFrame in Spark Scala 未涵盖如何同时重命名和选择列

【问题讨论】:

标签: scala apache-spark apache-spark-sql


【解决方案1】:

这是一种方法;使用模式匹配检查名称是否存在于lookup 中,如果不使用原始名称,则为该列指定别名:

val cols = someDF.columns.map(name => lookup.get(name) match { 
  case Some(newname) => col(name).as(newname) 
  case None => col(name) 
})

someDF.select(cols: _*).show
+---+------+------+
| id|animal|letter|
+---+------+------+
|  8|   bat|     h|
| 64| mouse|     t|
|-27| horse|     x|
+---+------+------+

如果您只需要查找中的列:

val cols = someDF.columns.collect(name => lookup.get(name) match { 
  case Some(newname) => col(name).as(newname) 
})

someDF.select(cols: _*).show
+---+------+
| id|animal|
+---+------+
|  8|   bat|
| 64| mouse|
|-27| horse|
+---+------+

【讨论】:

  • 谢谢@Psidom - 意识到我的问题不是 100% 清楚。我还想删除不在地图中的列。 case None => None 会覆盖吗?
  • 如果您只需要lookup 中的列,您可以使用collect,它将删除不匹配的列而不是map。查看更新 -
  • 这可行,但我收到类型检查错误 - 知道如何指定正确的类型吗? Type mismatch, expected: PartialFunction[String, NotInferedB], actual: Nothing => Column
  • 想通了:` val x: PartialFunction[String, Column] = { name: String => lookup.get(name) match { case Some(newname) => col(name).as (新名称):列 } } val cols = dataOut.columns.collect{x}`
猜你喜欢
  • 2018-02-12
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2018-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多