Сравнение значений объектов столбцов в Spark с Scala

#scala #apache-spark #apache-spark-sql

#scala #apache-spark #apache-spark-sql

Вопрос:

Я пишу методы в Scala, которые принимают аргументы столбца и возвращают столбец. В них я пытаюсь сравнить значения столбцов (от целых чисел до дат), используя логику, аналогичную приведенной ниже, но столкнулся с сообщением об ошибке.

lit() Это только для примера. По правде говоря, я передаю столбцы из a DataFrame.select() в метод для выполнения вычислений. Мне нужно сравнить, используя эти столбцы.

 val test1 = lit(3)
val test2 = lit(4)

if (test1 > test2) { 
    print("tuff")
}
 

Сообщение об ошибке.

 Error : <console>:96: error: type mismatch;
 found   : org.apache.spark.sql.Column
 required: Boolean
       if (test1 > test2) {
 

Каков правильный способ сравнения объектов столбцов в Spark? В документации столбца указан > оператор как допустимый для сравнения.

Редактировать: вот очень надуманный пример использования, предполагающий, что столбцы, передаваемые в функцию, представляют собой даты, которые необходимо сравнить по деловым соображениям с возвращаемым целочисленным значением, которое также имеет некоторое значение для бизнеса.

 someDataFrame.select(
   $"SomeColumn", 
   computedColumn($"SomeColumn1", $"SomeColumn2").as("MyComputedColumn")
)
 

Где computedColumn было бы

 def computedColumn(col1 : Column, col2: Column) : Column = { 
      val returnCol : Column = lit(0)    
      if (col1 > col2) { 
         returnCol = lit(4)
      } 
} 
 

За исключением фактического использования, существует гораздо больше логики if / else, которая должна выполняться computedColumn , при этом конечным результатом является возвращаемый столбец, который будет добавлен в выходные данные select.

Ответ №1:

Вы можете использовать when для выполнения условного сравнения:

 someDataFrame.select(
   $"SomeColumn", 
   when($"SomeColumn1" > $"SomeColumn2", 4).otherwise(0).as("MyComputedColumn")
)
 

Если вы предпочитаете писать функцию:

 def computedColumn(col1 : Column, col2: Column) : Column = { 
    when(col1 > col2, 4).otherwise(0)
} 

someDataFrame.select(
   $"SomeColumn", 
   computedColumn($"SomeColumn1", $"SomeColumn2").as("MyComputedColumn")
)
 

Комментарии:

1. Это, безусловно, то, что я мог бы реализовать, но действительно ли нет способа использовать традиционную логику Scala if / else / else if для типа объекта столбца? Логика, которую я собираюсь реализовать, станет довольно надежной (6-7 условий), и я беспокоюсь о удобочитаемости формата when / иначе в будущем. Я думал о том, чтобы, возможно, сделать Column.toString().toWhateverDataType, но это показалось немного странным.

2. @Godwin если вы работаете с Spark, вам нужно привыкнуть к синтаксису Spark. Для меня использование when / otherwise намного более читаемо, чем if/else просто потому, что я к нему привык. Это путь вперед, если вы собираетесь работать с большими данными и Spark.