Передать несколько условий в виде строки в предложении where в Spark - PullRequest
0 голосов
/ 24 мая 2018

Я пишу следующий код в Spark с API DataFrame.

val cond = "col("firstValue") >= 0.5 & col("secondValue") >= 0.5 & col("thirdValue") >= 0.5"
val Output1 = InputDF.where(cond)

Я передаю все условия в виде строк из внешних аргументов, но он выдает ошибку синтаксического анализа, поскольку cond должен иметь типColumn.

Например:

col("firstValue") >= 0.5 & col("secondValue") >= 0.5 & col("thirdValue") >= 0.5

Поскольку я хочу динамически передавать несколько условий, как я могу преобразовать String в Column?

Edit

Есть ли что-нибудь, через что я могу внешне прочитать список условий как Column, потому что я не нашел ничего, чтобы преобразовать String в Column, используя код Scala.

1 Ответ

0 голосов
/ 24 мая 2018

Полагаю, вы можете захотеть сделать что-то вроде следующего:

InputDF.where("firstValue >= 0.5 and secondValue >= 0.5 and thirdValue >= 0.5")

Ошибка, с которой вы сталкиваетесь, является ошибкой разбора во время выполнения, если ошибка была вызвана неверным типом, переданным в нее, не будетдаже скомпилированы.

Как вы можете видеть в официальной документации (здесь приведено для Spark 2.3.0), метод where может принимать последовательность Column с (например,в вашем последнем фрагменте) или строку, представляющую предикат SQL (как в моем примере).

Предикат SQL будет интерпретироваться Spark.Однако я считаю, что стоит упомянуть, что вам может быть интересно составить Column вместо конкатенации строк, поскольку первый подход минимизирует поверхность ошибки, избавляясь от целых классов возможных ошибок (например, ошибок синтаксического анализа).

То же самое можно сделать с помощью следующего кода:

InputDF.where(col("firstValue") >= 0.5 and col("secondValue") >= 0.5 and col("thirdValue") >= 0.5)

или более кратко:

import spark.implicits._ // necessary for the $"" notation
InputDF.where($"firstValue" >= 0.5 and $"secondValue" >= 0.5 and $"thirdValue" >= 0.5)

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

def allSatisfied(condition: Column, conditions: Column*): Column =
    conditions.foldLeft(condition)(_ and _)

InputDF.where(allSatisfied($"firstValue" >= 0.5, $"secondValue" >= 0.5, $"thirdValue" >= 0.5))

Вы можете достичь того же с помощью строк, конечно, но это в конечном итоге будет менее надежным:

def allSatisfied(condition: String, conditions: String*): String =
    conditions.foldLeft(condition)(_ + " and " + _)

InputDF.where(allSatisfied("firstValue >= 0.5", "secondValue >= 0.5", "thirdValue >= 0.5"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...