Dela via


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

En användardefinierad funktion (UDF) är en funktion som definieras av en användare, vilket gör att anpassad logik kan återanvändas i användarmiljön. Azure Databricks har stöd för många olika typer av UDF:er för distribution av utökningsbar logik. Den här artikeln beskriver några av de allmänna styrkorna och begränsningarna i UDF:er.

Kommentar

Alla former av UDF:er är inte tillgängliga i alla körningsmiljöer i Azure Databricks. Om du arbetar med Unity Catalog kan du läsa Användardefinierade funktioner (UDF:er) i Unity Catalog.

Definiera anpassad logik utan serialiseringsstraff

Azure Databricks ärver mycket av sina UDF-beteenden från Apache Spark, inklusive effektivitetsbegränsningarna för många typer av UDF:er. Se Vilka UDF:er är mest effektiva?.

Du kan på ett säkert sätt modularisera din kod utan att behöva oroa dig för potentiella effektivitetsavvägningar som är associerade med UDF:er. För att göra det måste du definiera din logik som en serie inbyggda Spark-metoder med hjälp av SQL eller Spark DataFrames. Följande SQL- och Python-funktioner kombinerar till exempel inbyggda Spark-metoder för att definiera en enhetskonvertering som en återanvändbar funktion:

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)

Om du vill köra ovanstående UDF:er kan du skapa exempeldata.

Vilka UDF:er är mest effektiva?

UDF:er kan medföra betydande flaskhalsar för bearbetning i kodkörningen. Azure Databricks använder automatiskt ett antal olika optimerare för kod som skrivits med apache Spark, SQL och Delta Lake-syntax. När anpassad logik introduceras av UDF:er har dessa optimerare inte möjlighet att effektivt planera uppgifter kring den här anpassade logiken. Dessutom medför logik som körs utanför JVM ytterligare kostnader kring data serialisering.

Kommentar

Azure Databricks optimerar många funktioner med Photon om du använder Photon-aktiverad beräkning. Endast funktioner som kedjar samman Spark SQL för DataFrame-kommandon kan optimeras av Photon.

Vissa UDF:er är effektivare än andra. Prestandamässigt:

  • Inbyggda funktioner kommer att vara snabbast på grund av Azure Databricks-optimerare.
  • Kod som körs i JVM (Scala, Java, Hive UDF:er) kommer att vara snabbare än Python-UDF:er.
  • Pandas UDF:er använder Arrow för att minska serialiseringskostnader som är associerade med Python-UDF:er.
  • Python-UDF:er fungerar bra för procedurlogik, men bör undvikas för produktions-ETL-arbetsbelastningar på stora datauppsättningar.

Kommentar

I Databricks Runtime 12.2 LTS och nedan stöds inte Python-skalära UDF:er och Pandas UDF:er i Unity Catalog i kluster som använder läget för delad åtkomst. Dessa UDF:er stöds i Databricks Runtime 13.3 LTS och senare för alla åtkomstlägen.

I Databricks Runtime 14.1 och nedan stöds inte scalar-UDF:er i Unity Catalog i kluster som använder läget för delad åtkomst. Dessa UDF:er stöds för alla åtkomstlägen i Databricks Runtime 14.2 och senare.

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

Typ Optimerad Körningsmiljö
Hive UDF Nej JVM
Python UDF Nej Python
Pandas UDF Nej Python (pil)
Scala UDF Nej JVM
Spark SQL Ja JVM (foton)
Spark DataFrame Ja JVM (foton)

När ska du använda en UDF?

En stor fördel med UDF:er är att användarna kan uttrycka logik på välbekanta språk, vilket minskar de mänskliga kostnaderna för refaktoriseringskod. För ad hoc-frågor, manuell datarensning, undersökande dataanalys och de flesta åtgärder på små eller medelstora datauppsättningar är det osannolikt att kostnaderna för svarstid som är associerade med UDF:er uppväger kostnader som är associerade med refaktoriseringskod.

För ETL-jobb, strömningsåtgärder, åtgärder på mycket stora datauppsättningar eller andra arbetsbelastningar som körs regelbundet eller kontinuerligt ger refaktoriseringslogik för att använda inbyggda Apache Spark-metoder snabbt utdelning.

Exempeldata till exempel UDF:er

Kodexemplen i den här artikeln använder UDF:er för att konvertera temperaturer mellan Celcius och Farenheit. Om du vill köra dessa funktioner kan du skapa en exempeldatauppsättning med följande Python-kod:

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")