Python Pyspark UDF可以工作,除非我调用任何内置函数

Python Pyspark UDF可以工作,除非我调用任何内置函数,python,apache-spark,pyspark,databricks,azure-databricks,Python,Apache Spark,Pyspark,Databricks,Azure Databricks,我正在尝试实现pyspark函数来执行半偶数舍入。问题是,如果我只是返回传入的值,构建就会工作。如果它做了其他事情,我会得到一个模糊的错误。以下是我的udf的工作原理: @udf(returnType=DecimalType()) def round_half_even(number): return number 我只是在数据帧上的select中调用udf,如下所示: df1 = spark.read... df1.select( df1.COST, round_half

我正在尝试实现pyspark函数来执行半偶数舍入。问题是,如果我只是返回传入的值,构建就会工作。如果它做了其他事情,我会得到一个模糊的错误。以下是我的udf的工作原理:

@udf(returnType=DecimalType())
def round_half_even(number):
  return number
我只是在数据帧上的select中调用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环境似乎并不真正可用,但这应该是spark的问题,而不是我的问题

编辑:复习完这个问题后,我意识到spark有一个bround函数,它可以进行半甚至四舍五入。我仍然需要解决这个问题,因为我有几个UDF都因为同样的原因失败,而这一个似乎是最简单的

更新: 空检查确实是导致我的udf失败的原因,因此我对它进行了如下修改(如Hristo Iliev所建议的):


这使它得以完成,但现在我得到的只是目标中的空值,即使在上面的示例中传入文本值时也是如此。我已经验证了应该有成百上千个非空值。

您的参数“number”可能是无的,只需在调用round方法之前进行检查即可


PS:PySpark UDF中提供了所有Python内置函数。如果要调用任何其他方法/库,则必须在UDF中导入它

如果列中有
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不是None
。整数和浮点零在布尔上下文中计算为false。

您能显示
udf
调用吗?您的udf失败,因为您没有纠正丢失的(
NULL
在SQL中,
None
在Python中)值。感谢指针user10938362。如果你可以把它作为一个答案而不是一个评论,我可以接受。
If number:
是一种不好的做法,因为当
number
0
时,它会导致函数返回
None
(零在布尔上下文中计算为false)。如果数字不是无,则正确的检查是
@udf(returnType=DecimalType())
def round_half_even(number):
  return round(number, 0) if number is not None else None