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šší.
Funkce definované uživatelem (UDF) v jazyce Python lze zaregistrovat v Unity Catalog pomocí SQL syntaxe v prostředí Databricks Runtime 13.3 LTS a vyšších verzích. Viz uživatelem definované funkce (UDF) v Unity Catalog.
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 se registrují v Unity Catalog a mají přidružená oprávnění, zatímco funkce definované uživatelem vytvořené v rámci poznámkového bloku jsou relacní a platné pouze pro 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 SQL a Python skalární UDF zaregistrované v Unity Catalog.
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 v name
column a přidání hodnoty do nového columnname_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 Unity Catalog 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 table 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 table Pythonu (UDTFs) můžou vracet více řádků a columns pro každý vstupní řádek. V následujícím příkladu každá hodnota v column skóre odpovídá list kategorií. UDTF je definován pro rozdělení čárkami oddělených list do více řádků. Viz uživatelem definované funkce table 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.