Pyspark UDF работает, если я не вызываю какие-либо встроенные функции - PullRequest
0 голосов
/ 13 марта 2020

Я пытаюсь реализовать функцию pyspark для выполнения округления до половины. Проблема в том, что если я просто верну переданное значение, сборка работает. Если он делает что-то еще, я получаю неясную ошибку. Вот мой udf, как он работает:

@udf(returnType=DecimalType())
def round_half_even(number):
  return number

Я просто вызываю udf в выборке на фрейме данных, например:

df1 = spark.read...
df1.select(
    df1.COST,
    round_half_even(f.lit(17.45)).alias('V_COST_TOTAL_CALC')
)

Но эта версия, которая на самом деле выполняет округление, терпит неудачу :

@udf(returnType=DecimalType())
def round_half_even(number):
  return round(number, 0)

С этой ошибкой:

TypeError: type NoneType doesn't define __round__ method

Я довольно новичок в Python, поэтому я не знаю, как отследить это. Похоже, что среда python на самом деле недоступна, но это должна быть проблема спарка, а не моя.

РЕДАКТИРОВАТЬ: я понял, после рассмотрения этого вопроса, что спарк имеет функцию bround, которая делает половину даже округления. Мне все еще нужно решить эту проблему, потому что у меня есть несколько UDF, которые все отказывают по одной и той же причине, и этот, кажется, самый простой.

ОБНОВЛЕНИЕ: проверка на ноль действительно была причиной того, что мой udf не удался, поэтому я изменил это так (как подсказал Христо Илиев):

@udf(returnType=DecimalType())
def round_half_even(number):
  return round(number, 0) if number is not None else None

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

Ответы [ 2 ]

1 голос
/ 14 марта 2020

Если в столбце есть значения NULL, PySpark передает None для таких значений, а ваша функция round() не обрабатывает None. Что-то вроде следующего должно сделать:

@udf(returnType=DecimalType())
def round_half_even(number):
  return round(number, 0) if number is not None else None

Обратите внимание, что правильная проверка для не- None значений - var is not None. Целочисленные нули и числа с плавающей точкой оцениваются как ложные в логическом контексте.

0 голосов
/ 14 марта 2020

Ваш параметр 'число' может быть Нет, просто поставьте галочку перед вызовом метода округления.

PS: Все встроенные функции Python доступны внутри PySpark UDF. Если вы хотите вызвать любой другой метод / библиотеку, вам придется импортировать его в UDF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...