Python Pyspark UDF可以工作,除非我调用任何内置函数
我正在尝试实现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
@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