用戶定義標量函數- Python
本文包含Python用戶定義函數(UDF)示例。它展示了如何注冊udf,如何調用udf,以及在Spark SQL中關於子表達式求值順序的注意事項。
將函數注冊為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不是null and strlen(s) >為1")#不保證
這在哪裏
條款不保證strlen
在過濾空值之後調用的UDF。
要執行正確的空檢查,我們建議您執行以下任一操作:
使UDF本身具有空感知能力,並在UDF本身內部執行空檢查
使用
如果
或情況下當
表達式執行空檢查並在條件分支中調用UDF
火花.udf.注冊(“strlen_nullsafe”,λ年代:len(年代)如果不年代是沒有一個其他的-1,“int”)火花.sql("select s from test1 where s不是null and strlen_nullsafe(s) > 1")//好吧火花.sql("select s from test1 where if(s is not null, strlen(s), null) > 1")//好吧