自定义标量函数- Python
本文包含Python用户定义函数(UDF)示例。它展示了如何注册udf,如何调用udf,并提供了关于Spark SQL中子表达式求值顺序的注意事项。
请注意
在使用共享访问模式的集群上,Unity Catalog不支持Python UDF和UDAF(用户定义的聚合函数)。
将函数注册为UDF
def的平方(年代):返回年代*年代火花.udf.注册(“squaredWithPython”,的平方)
您可以选择设置UDF的返回类型。默认返回类型为StringType
.
从pyspark.sql.types进口LongTypedefsquared_typed(年代):返回年代*年代火花.udf.注册(“squaredWithPython”,squared_typed,LongType())
在Spark SQL中调用UDF
火花.范围(1,20.).createOrReplaceTempView(“测试”)
%sql选择id,squaredWithPython(id)作为id_squared从测验
在数据框架中使用UDF
从pyspark.sql.functions进口udf从pyspark.sql.types进口LongTypesquared_udf=udf(的平方,LongType())df=火花.表格(“测试”)显示(df.选择(“id”,squared_udf(“id”).别名(“id_squared”)))
或者,你可以使用注释语法声明相同的UDF:
从pyspark.sql.functions进口udf@udf(“长”)defsquared_udf(年代):返回年代*年代df=火花.表格(“测试”)显示(df.选择(“id”,squared_udf(“id”).别名(“id_squared”)))
求值顺序和空值检查
Spark SQL(包括SQL、DataFrame和Dataset API)不保证子表达式的求值顺序。特别是,运算符或函数的输入不一定按从左到右或任何其他固定顺序求值。例如,逻辑和
而且或
表达式没有从左到右的“短路”语义。
因此,依赖布尔表达式的副作用或求值顺序是危险的在哪里
而且有
子句,因为这样的表达式和子句可以在查询优化和计划期间重新排序。具体来说,如果UDF依赖SQL中的短路语义进行空检查,则不能保证在调用UDF之前进行空检查。例如,
火花.udf.注册(“strlen”,λ年代:len(年代),“int”)火花.sql(“select s from test1 where s not null and strlen(s) > 1”)#不保证
这在哪里
条款不保证strlen
在过滤掉空值后调用的UDF。
要执行正确的空检查,我们建议您执行以下任何一种方法:
使UDF本身为空感知的,并在UDF内部执行空检查
使用
如果
或情况下当
表达式执行空检查并在条件分支中调用UDF
火花.udf.注册(“strlen_nullsafe”,λ年代:len(年代)如果不年代是没有一个其他的-1,“int”)火花.sql(“select s from test1 where s not null and strlen_nullsafe(s) > 1”)//好吧火花.sql(“select s from test1 where if(s) not null, strlen(s), null) > 1”)//好吧