#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.