什麼是使用者定義函式 (UDF)?
使用者定義函式 (UDF) 是由使用者定義的函式,可讓使用者在使用者環境中重複使用自訂邏輯。 Azure Databricks 支援許多不同類型的 UDF,以允許散發可延伸邏輯。 本文介紹UDF的一些一般優勢和限制。
注意
並非所有形式的 UDF 都可在 Azure Databricks 的所有執行環境中使用。 如果您使用 Unity 目錄,請參閱 Unity 目錄中的使用者定義函式 (UDF)。
如需 UDF 的詳細資訊,請參閱下列文章:
- Unity 目錄中的使用者定義函式 (UDF)
- pandas 用戶定義函式
- 用戶定義的純量函式 - Python
- 什麼是 Python 使用者定義數據表函式?
- 用戶定義的純量函式 - Scala
- 用戶定義聚合函數 - Scala
定義自定義邏輯而不受到串行化處罰
Azure Databricks 會從 Apache Spark 繼承其大部分的 UDF 行為,包括許多 UDF 類型的效率限制。 請參閱 哪些 UDF 最有效率?。
您可以安全地將程式代碼模組化,而不必擔心與 UDF 相關聯的潛在效率取捨。 若要這樣做,您必須使用 SQL 或 Spark DataFrame 將邏輯定義為一系列 Spark 內建方法。 例如,下列 SQL 和 Python 函式會結合 Spark 內建方法,將單位轉換定義為可重複使用的函式:
SQL
CREATE FUNCTION convert_f_to_c(unit STRING, temp DOUBLE)
RETURNS DOUBLE
RETURN CASE
WHEN unit = "F" THEN (temp - 32) * (5/9)
ELSE temp
END;
SELECT convert_f_to_c(unit, temp) AS c_temp
FROM tv_temp;
Python
def convertFtoC(unitCol, tempCol):
from pyspark.sql.functions import when
return when(unitCol == "F", (tempCol - 32) * (5/9)).otherwise(tempCol)
from pyspark.sql.functions import col
df_query = df.select(convertFtoC(col("unit"), col("temp"))).toDF("c_temp")
display(df_query)
若要執行上述 UDF,您可以建立 範例數據。
哪些 UDF 最有效率?
UDF 可能會對程式代碼執行造成顯著的處理瓶頸。 Azure Databricks 會自動針對以隨附的 Apache Spark、SQL 和 Delta Lake 語法撰寫的程式代碼,使用許多不同的優化器。 當UDF引進自定義邏輯時,這些優化工具無法有效率地規劃此自定義邏輯的工作。 此外,在 JVM 外部執行的邏輯在數據串行化方面有額外的成本。
注意
如果您使用已啟用 Photon 的計算,Azure Databricks 會使用 Photon 優化許多函式。 只有將Spark SQL鏈結在一起的DataFrame命令的函式,才能由 Photon 優化。
某些 UDF 比其他 UDF 更有效率。 在效能方面:
- 內建函式會因為 Azure Databricks 優化器而最快。
- 在 JVM 中執行的程式代碼(Scala、Java、Hive UDF)會比 Python UDF 快。
- Pandas UDF 使用 Arrow 來降低與 Python UDF 相關聯的串行化成本。
- Python UDF 適用於程式邏輯,但應該避免大型數據集上的生產 ETL 工作負載。
注意
在 Databricks Runtime 12.2 LTS 和以下版本中,在使用共用存取模式的叢集上,Unity 目錄中不支援 Python 純量 UDF 和 Pandas UDF。 在所有存取模式中,Databricks Runtime 13.3 LTS 和更新版本都支持這些 UDF。
在 Databricks Runtime 14.1 和以下版本中,在使用共用存取模式的叢集上不支援 Scala 純量 UDF。 Databricks Runtime 14.2 和更新版本中的所有存取模式都支持這些 UDF。
在 Databricks Runtime 13.3 LTS 和更新版本中,您可以使用 SQL 語法向 Unity 目錄註冊純量 Python UDF。 請參閱 Unity 目錄中的使用者定義函式 (UDF)。
類型 | 已最佳化 | 執行環境 |
---|---|---|
Hive UDF | No | JVM |
Python UDF | No | Python |
Pandas UDF | No | Python (箭頭) |
Scala UDF | No | JVM |
Spark SQL | Yes | JVM (Photon) |
Spark DataFrame | Yes | JVM (Photon) |
何時應該使用UDF?
UDF 的主要優點是,他們允許使用者以熟悉的語言表達邏輯,降低與重構程式代碼相關聯的人力成本。 針對臨機操作查詢、手動數據清理、探勘數據分析,以及小型或中型數據集上的大部分作業,與 UDF 相關聯的延遲額外負荷成本不太可能超過與重構程式代碼相關聯的成本。
對於 ETL 作業、串流作業、非常大型數據集上的作業,或定期或持續執行的其他工作負載,重構邏輯以使用原生 Apache Spark 方法快速支付股息。
例如UDF的範例數據
本文中的程式代碼範例會使用UDF來轉換 Celcius 與 Farenheit 之間的溫度。 如果您想要執行這些函式,您可以使用下列 Python 程式代碼來建立範例數據集:
import numpy as np
import pandas as pd
Fdf = pd.DataFrame(np.random.normal(55, 25, 10000000), columns=["temp"])
Fdf["unit"] = "F"
Cdf = pd.DataFrame(np.random.normal(10, 10, 10000000), columns=["temp"])
Cdf["unit"] = "C"
df = spark.createDataFrame(pd.concat([Fdf, Cdf]).sample(frac=1))
df.cache().count()
df.createOrReplaceTempView("tv_temp")