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



我正在尝试实现一个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所建议的(:

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

这使得它得以完成,但现在我得到的只是目标中的null值,即使是像上面的例子中那样传递文本值。我已经验证了应该有成百上千的非空值。

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

您的参数'number'可能为None,只需在调用round方法之前进行检查即可。

PS:所有Python内置函数都可以在PySpark UDF中使用。如果您想调用任何其他方法/库,则必须将其导入UDF中。

最新更新