Co jsou uživatelem definované funkce (UDF)?
Uživatelem definované funkce (UDF) umožňují opakovaně používat a sdílet kód, který rozšiřuje integrované funkce v Azure Databricks. Funkce definované uživatelem slouží k provádění konkrétních úloh, jako jsou složité výpočty, transformace nebo vlastní manipulace s daty.
Poznámka:
V clusterech s režimem sdíleného přístupu se skalární funkce definované uživatelem v Pythonu podporují v Databricks Runtime 13.3 LTS a vyšší, zatímco uživatelem definované funkce Scala se podporují ve službě Databricks Runtime 14.2 a vyšší.
Skalární uživatelem definované uživatelem Pythonu je možné zaregistrovat v katalogu Unity pomocí syntaxe SQL v Databricks Runtime 13.3 LTS a vyšší. Viz uživatelem definované funkce (UDF) v katalogu Unity.
Kdy byste měli použít funkci definovanou uživatelem?
UDF používejte pro logiku, která se obtížně vyjadřuje pomocí integrovaných funkcí Apache Sparku. Integrované funkce Apache Sparku jsou optimalizované pro distribuované zpracování a obecně nabízejí lepší výkon ve velkém měřítku. Další informace najdete v tématu Funkce.
Databricks doporučuje funkce definované uživatelem pro ad hoc dotazy, ruční čištění dat, průzkumnou analýzu dat a operace s malými až středními datovými sadami. Mezi běžné případy použití UDF patří šifrování a dešifrování dat, hashování, analýza JSON a ověřování.
Pro operace s velmi velkými datovými sadami a všemi úlohami, které běží pravidelně nebo nepřetržitě, včetně úloh ETL a operací streamování, použijte metody Apache Spark.
Registrované uživatelem a definované uživatelem definované uživatelem
Funkce definované uživatelem vytvořené pomocí SQL jsou zaregistrované v katalogu Unity a mají přidružená oprávnění, zatímco definované uživatelem vytvořené v poznámkovém bloku jsou založené na relacích a jsou omezené na aktuální SparkSession.
Uživatelem na základě relací můžete definovat a přistupovat k němu pomocí libovolného jazyka podporovaného službou Azure Databricks. Uživatelem definované funkce můžou být skalární nebo jiné než skalární.
Poznámka:
V současné době jsou v DBSQL k dispozici pouze skalární uživatelem definované uživatelem SQL a Pythonu zaregistrované v katalogu Unity.
Skalární funkce definované uživatelem
Skalární funkce definované uživatelem pracují na jednom řádku a vracejí jednu hodnotu pro každý řádek. Následující příklad používá skalární UDF k výpočtu délky každého názvu ve name
sloupci a přidání hodnoty do nového sloupce name_length
:
+-------+-------+
| name | score |
+-------+-------+
| alice | 10.0 |
| bob | 20.0 |
| carol | 30.0 |
| dave | 40.0 |
| eve | 50.0 |
+-------+-------+
-- Create a SQL UDF for name length
CREATE OR REPLACE FUNCTION get_name_length(name STRING)
RETURNS INT
RETURN LENGTH(name);
-- Use the UDF in a SQL query
SELECT name, get_name_length(name) AS name_length
FROM your_table;
+-------+-------+-------------+
| name | score | name_length |
+-------+-------+-------------+
| alice | 10.0 | 5 |
| bob | 20.0 | 3 |
| carol | 30.0 | 5 |
| dave | 40.0 | 4 |
| eve | 50.0 | 3 |
+-------+-------+-------------+
K implementaci v poznámkovém bloku Databricks pomocí PySparku:
from pyspark.sql.functions import udf
from pyspark.sql.types import IntegerType
@udf(returnType=IntegerType())
def get_name_length(name):
return len(name)
df = df.withColumn("name_length", get_name_length(df.name))
# Show the result
display(df)
Další informace najdete v tématu Uživatelem definované funkce (UDF) v katalogu Unity a uživatelem definované skalární funkce – Python.
Agregační funkce definované uživatelem (UDAF)
Uživatelem definované agregační funkce (UDAF) pracují s více řádky a vracejí jeden agregovaný výsledek. V následujícím příkladu je definován UDAF, který agreguje skóre.
from pyspark.sql.functions import pandas_udf
from pyspark.sql import SparkSession
import pandas as pd
# Define a pandas UDF for aggregating scores
@pandas_udf("int")
def total_score_udf(scores: pd.Series) -> int:
return scores.sum()
# Group by name length and aggregate
result_df = (df.groupBy("name_length")
.agg(total_score_udf(df["score"]).alias("total_score")))
display(result_df)
+-------------+-------------+
| name_length | total_score |
+-------------+-------------+
| 3 | 70.0 |
| 4 | 40.0 |
| 5 | 40.0 |
+-------------+-------------+
Viz uživatelem definované funkce pandas pro agregační funkce definované uživatelem v Pythonu a uživatelem – Scala.
Uživatelem definované funkce tabulek v Pythonu (UDTFs)
Důležité
Tato funkce je ve verzi Public Preview.
Poznámka:
Funkce definované uživatelem v Pythonu jsou k dispozici v Databricks Runtime 14.3 LTS a vyšší.
Uživatelem definované funkce tabulek v Pythonu (UDTFs) můžou vracet více řádků a sloupců pro každý vstupní řádek. V následujícím příkladu každá hodnota ve sloupci skóre odpovídá seznamu kategorií. Funkce UDTF je definována pro rozdělení čárkami odděleného seznamu na více řádků. Viz uživatelem definované funkce tabulek v Pythonu (UDTFs)
+-------+-------+-----------------+
| name | score | categories |
+-------+-------+-----------------+
| alice | 10.0 | math,science |
| bob | 20.0 | history,math |
| carol | 30.0 | science,history |
| dave | 40.0 | math,art |
| eve | 50.0 | science,art |
+-------+-------+-----------------+
from pyspark.sql.functions import udtf
@udtf(returnType="score: int, categories: string, name: string")
class ScoreCategoriesUDTF:
def eval(self, name: str, score: float, categories: str):
category_list = categories.split(',')
for category in category_list:
yield (name, score, category)
# Apply the UDTF
result_df = df.select(ScoreCategoriesUDTF(df.score, df.categories, df.name))
display(result_df)
+-------+-------+----------+
| name | score | category |
+-------+-------+----------+
| alice | 10.0 | math |
| alice | 10.0 | science |
| bob | 20.0 | history |
| bob | 20.0 | math |
| carol | 30.0 | science |
| carol | 30.0 | history |
| dave | 40.0 | math |
| dave | 40.0 | art |
| eve | 50.0 | science |
| eve | 50.0 | art |
+-------+-------+----------+
Důležité informace o výkonu
- Předdefinované funkce a funkce definované uživatelem SQL jsou nejúčinnější dostupnou možností.
- Uživatelem definované funkce Scala jsou obecně rychlejší, protože se spouštějí v prostředí Java Virtual Machine (JVM) a zabraňují režijním nákladům na přesun dat z prostředí JVM a z něj.
- Uživatelem definované funkce Pythonu a uživatelem definované uživatelem Pandas jsou pomalejší než funkce definované uživatelem Scala, protože vyžadují serializaci dat a přesun z JVM do interpretu Pythonu. Uživatelem definované funkce Pandas až 100x rychlejší než definované uživatelem Pythonu, protože používají Apache Arrow ke snížení nákladů na serializaci.