我想改变数据框中列的顺序,并发现正确的方法如下:val reorderedColumnNames: Array[String] = ??? // the new order of columns
val result: DataFrame = dataFrame.select(reorderedColumnNames.head, reorderedColumnNames.tail: _*)
我的问题是:为什么不能像下面这样使用冒号": _*"应该让你的集合(Seq,列表或数组)的所有元素?val result: DataFrame = dataFrame.select(reorderedColumnNames: _*)
我不明白为什么第二种方式不被Spark接受(并产生错误),因为两种方式都应该是等效的
Dataset
的API要求这样做
首先,Dataframe
(据我回忆,从2.0开始,或多或少)在实现方面只是Dataset[Row]
,所以你必须检查Dataset的API文档。
看看select
方法,有两种实现可供选择。
def select(col: String, cols: String*): DataFrame
它接受一个String
,后跟任意数量的String
。
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 = {}
^
编译器不满意