Dela via


Vad är användardefinierade funktioner (UDF:er)?

Med användardefinierade funktioner (UDF:er) kan du återanvända och dela kod som utökar inbyggda funktioner i Azure Databricks. Använd UDF:er för att utföra specifika uppgifter, till exempel komplexa beräkningar, transformeringar eller anpassade datamanipuleringar.

Kommentar

I kluster med läget för delad åtkomst stöds python-skalära UDF:er i Databricks Runtime 13.3 LTS och senare, medan Scala UDF:er stöds i Databricks Runtime 14.2 och senare.

Python-skalära UDF:er kan registreras i Unity Catalog med sql-syntax i Databricks Runtime 13.3 LTS och senare. Se Användardefinierade funktioner (UDF: er) i Unity Catalog.

När ska du använda en UDF?

Använd UDF:er för logik som är svår att uttrycka med inbyggda Apache Spark-funktioner. Inbyggda Apache Spark-funktioner är optimerade för distribuerad bearbetning och erbjuder i allmänhet bättre prestanda i stor skala. Mer information finns i Funktioner.

Databricks rekommenderar UDF:er för ad hoc-frågor, manuell datarensning, undersökande dataanalys och åtgärder på små till medelstora datamängder. Vanliga användningsfall för UDF:er är datakryptering och dekryptering, hashning, JSON-parsning och validering.

Använd Apache Spark-metoder för åtgärder på mycket stora datauppsättningar och alla arbetsbelastningar som körs regelbundet eller kontinuerligt, inklusive ETL-jobb och strömningsåtgärder.

Registrerade och sessionsomfångade UDF:er

UDF:er som skapats med SQL är registrerade i Unity Catalog och har associerade behörigheter, medan UDF:er som skapats i din notebook-fil är sessionsbaserade och är begränsade till den aktuella SparkSession.

Du kan definiera och komma åt sessionsbaserade UDF:er med valfritt språk som stöds av Azure Databricks. UDF:er kan vara skalära eller icke-skalära.

Kommentar

För närvarande är endast SQL- och Python-skalära UDF:er registrerade i Unity Catalog tillgängliga i DBSQL.

Skalära UDF:er

Skalära UDF:er fungerar på en enskild rad och returnerar ett enda värde för varje rad. I följande exempel används en skalär UDF för att beräkna längden på varje namn i en name kolumn och lägga till värdet i en ny kolumn 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      |
+-------+-------+-------------+

Så här implementerar du detta i en Databricks-notebook-fil med PySpark:

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)

Mer information finns i Användardefinierade funktioner (UDF: er) i Unity Catalog och Användardefinierade skalärfunktioner – Python.

Användardefinierade sammansättningsfunktioner (UDAF)

Användardefinierade aggregeringsfunktioner (UDAF:er) fungerar på flera rader och returnerar ett enda aggregerat resultat. I följande exempel definieras en UDAF som aggregerar poäng.

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    |
+-------------+-------------+

Se användardefinierade funktioner för Pandas för Python- och användardefinierade aggregeringsfunktioner – Scala.

Användardefinierade python-tabellfunktioner (UDF: er)

Viktigt!

Den här funktionen finns som allmänt tillgänglig förhandsversion.

Kommentar

Python-UDF:er är tillgängliga i Databricks Runtime 14.3 LTS och senare.

Användardefinierade python-tabellfunktioner (UDF: er) kan returnera flera rader och kolumner för varje indatarad. I följande exempel motsvarar varje värde i poängkolumnen en lista med kategorier. En UDTF definieras för att dela upp kommaavgränsad lista i flera rader. Se Användardefinierade tabellfunktioner i Python (UDF)

+-------+-------+-----------------+
| 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    |
+-------+-------+----------+

Prestandaöverväganden

  • Inbyggda funktioner och SQL UDF:er är det mest effektiva alternativet som är tillgängligt.
  • Scala-UDF:er är vanligtvis snabbare när de körs i den virtuella Java-datorn (JVM) och undviker att flytta data in och ut ur JVM.
  • Python UDF:er och Pandas UDF:er tenderar att vara långsammare än Scala UDF:er eftersom de kräver att data serialiseras och flyttas från JVM till Python-tolken. Pandas UDF:er upp till 100 x snabbare än Python-UDF:er eftersom de använder Apache Arrow för att minska serialiseringskostnaderna.