Ошибка на фолде при уменьшении в Spark / Scala - PullRequest
0 голосов
/ 04 февраля 2019

Учитывая, что у меня есть фрейм данных с некоторыми столбцами:

Почему это не работает?

val output3b = input.withColumn("sum", columnsToConcat.foldLeft(0)((x,y)=>(x+y)))

notebook:16: error: overloaded method value + with alternatives:
 (x: Int)Int <and>
 (x: Char)Int <and>
 (x: Short)Int <and>
 (x: Byte)Int
cannot be applied to (org.apache.spark.sql.Column)
val output3b = input.withColumn("sum", columnsToConcat.foldLeft(0)((x,y)=>(x+y))) // does work
                                                                           ^
notebook:16: error: type mismatch;
found   : Int
required: org.apache.spark.sql.Column
val output3b = input.withColumn("sum", columnsToConcat.foldLeft(0)((x,y)=>(x+y)))  

Но это работает?

val output3a = input.withColumn("concat", columnsToConcat.foldLeft(lit(0))((x,y)=>(x+y)))

Использование известной светящейся функции, кажется, сгладило несколько вещей, но я не уверен почему.

+---+----+----+----+----+----+------+
| ID|var1|var2|var3|var4|var5|concat|
+---+----+----+----+----+----+------+
|  a|   5|   7|   9|  12|  13|  46.0|
+---+----+----+----+----+----+------+

1 Ответ

0 голосов
/ 04 февраля 2019

Предварительные условия:

  • На основании сообщения компилятора и использования API мы можем сделать вывод, что columnsToConcat является Seq[o.a.s.sql.Column] или его эквивалентом.

  • По соглашению * методы 1011 * требуют функции, которая сопоставляется с аккумулятором (начальное значение).Вот Seq.foldLeft подпись

     def foldLeft[B](z: B)(op: (B, A) ⇒ B): B 
    
  • + в Scala - это метод, в частности синтаксический сахар для вызова .+.

Это означает, что в случае:

columnsToConcat.foldLeft(0)((x,y)=>(x+y))

равно

columnsToConcat.foldLeft(0)((x: Int, y: Column) => x + y)

и вы запрашиваете + метод Int (предполагаемый типаккумулятора - 0), а с Int - и для Int нет метода + (org.apache.spark.sql.Column) => Int (ошибка уже перечисляет доступные методы, и вряд ли неожиданно, чтотакой метод не существует), и в текущей области не существует неявного преобразования из Int в любой тип, обеспечивающий такой метод.

Во втором случае вы спрашиваете

columnsToConcat.foldLeft(lit(0))((x,y)=>(x+y))

- это

columnsToConcat.foldLeft(lit(0))((x: Column, y: Column) => x + y)

и + относится к Column.+ (как тип lit(0) равно Column) и такой метод , которыйпринимает Any и возвращает Column, существует.Поскольку Column <: Any ограничения типа выполняются

...