【问题标题】:Reason behind using x.head, x.tail: _* in Spark在 Spark 中使用 x.head、x.tail 的原因:_*
【发布时间】:2021-12-09 02:05:22
【问题描述】:

我想更改数据框中列的顺序,发现正确的方法如下: val reorderedColumnNames: Array[String] = ??? // the new order of columns

val result: DataFrame = dataFrame.select(reorderedColumnNames.head, reorderedColumnNames.tail: _*)

我的问题是: 如果冒号“:_*”应该为您提供集合的所有元素(Seq、List 或 Array),为什么不能像下面这样完成? val result: DataFrame = dataFrame.select(reorderedColumnNames: _*)

我不明白为什么 Spark 不接受第二种方式(并产生错误),因为这两种方式应该是等效的

【问题讨论】:

  • 这看起来更像是一个 scala 问题,而不是一个 spark 问题 - 但无可否认, spark 有助于理解上下文。为什么是蟒蛇?我已经编辑了标签,但可以随时恢复。

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


【解决方案1】:

Dataset的API要求是这样的。

首先,就实现而言,Dataframe(因为我记得或多或少是 2.0)只是一个 Dataset[Row],所以你必须检查API doc of Dataset

查看select 方法,有两种实现可供选择。

def select(col: String, cols: String*): DataFrame 

这个接受一个String,后跟任意数量的Strings。

def select(cols: Column*): DataFrame 

这个接受任意数量的Column 实例。

您的示例代码:val reorderedColumnNames: Array[String] 是一个字符串数组。因此,您只能使用该方法的字符串变体,这需要使用至少一个 String 参数,然后可能还有其他参数。 这就是为什么你不能直接扩展你的数组。

如果您要将Array[String] 转换为Array[Column],它会起作用,即:

val reorderedColumnNamesAsCols: Array[Column] = reorderedColumnNames.map(col(_))
dataFrame.select(reorderedColumnNamesAsCols: _*)

现在为什么不提出一个select(cols: String*) 变体呢?我不知道是否/为什么会提出这个建议,但我编译器不会很好地发挥它。 我们可以检查:

scala> class Test {
 |   def test(strs: String*): Unit = {}
 |   def test(nbrs: Integer*): Unit = {}
 | }
<console>:13: error: double definition:
def test(strs: String*): Unit at line 12 and
def test(nbrs: Integer*): Unit at line 13
have same type after erasure: (strs: Seq)Unit
     def test(nbrs: Integer*): Unit = {}
         ^

编译器不高兴。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-23
    • 2018-07-27
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 2023-04-08
    相关资源
    最近更新 更多