O que são funções definidas pelo usuário (UDFs)?

As funções definidas pelo usuário (UDFs) permitem que o senhor reutilize e compartilhe códigos que ampliam a funcionalidade integrada em Databricks. Use UDFs para executar tarefas específicas, como cálculos complexos, transformações ou manipulações de dados personalizadas.

Observação

Em clusters com modo de acesso compartilhado, os UDFs escalares de Python são suportados em Databricks Runtime 13.3 LTS e acima, enquanto os UDFs de Scala são suportados em Databricks Runtime 14.2 e acima.

Python Os UDFs escalares podem ser registrados em Unity Catalog usando a sintaxe de SQL em Databricks Runtime 13.3 LTS e acima. Consulte Funções definidas pelo usuário (UDFs) no Unity Catalog.

Quando você deve usar um UDF?

Use UDFs para lógica que seja difícil de expressar com funções integradas Apache Spark. integrada Apache Spark funções são otimizadas para processamento distribuído e geralmente oferecem melhor desempenho em escala. Para obter mais informações, consulte Funções.

Databricks recomenda UDFs para consultas ad hoc, limpeza manual de dados, análise exploratória de dados e operações em conjuntos de dados de pequeno e médio porte. Os casos de uso comuns de UDFs incluem criptografia e descriptografia de dados, hashing, análise de JSON e validação.

Use os métodos Apache Spark para operações em conjuntos de dados muito grandes e quaisquer cargas de trabalho que sejam executadas regularmente ou continuamente, incluindo ETL Job e operações de transmissão.

UDFs registrados e com escopo de sessão

Os UDFs criados com o uso do site SQL são registrados em Unity Catalog e têm permissões associadas, enquanto os UDFs criados no Notebook são baseados em sessões e têm escopo para o site SparkSession atual.

O senhor pode definir e acessar UDFs baseados em sessão usando qualquer linguagem suportada pela Databricks. Os UDFs podem ser escalares ou não escalares.

Observação

Atualmente, apenas as UDFs escalares SQL e Python registradas no Unity Catalog estão disponíveis no DBSQL.

UDFs escalares

As UDFs escalares operam em uma única linha e retornam um único valor para cada linha. O exemplo a seguir usa um UDF escalar para calcular o comprimento de cada nome em uma coluna name e adicionar o valor em uma nova coluna 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      |
+-------+-------+-------------+

Para implementar isso em um notebook Databricks usando 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)

Para obter mais informações, consulte Funções definidas pelo usuário (UDFs) em Unity Catalog e Funções escalares definidas pelo usuário - Python.

Funções agregadas definidas pelo usuário (UDAFs)

As funções agregadas definidas pelo usuário (UDAFs) operam em várias linhas e retornam um único resultado agregado. No exemplo a seguir, é definido um UDAF que agrega pontuações.

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

Consulte Pandas funções definidas pelo usuário para Python e Funções agregadas definidas pelo usuário - Scala.

Funções de tabela definidas pelo usuário (UDTFs) do Python

Prévia

Esse recurso está em Prévia Pública.

Observação

Python Os UDTFs estão disponíveis em Databricks Runtime 14.3 LTS e acima.

As funções de tabela definidas pelo usuário (UDTFs) do Python podem retornar várias linhas e colunas para cada linha de entrada. No exemplo a seguir, cada valor na coluna de pontuação corresponde a uma lista de categorias. Uma UDTF é definida para dividir a lista separada por vírgulas em várias linhas. Consulte Funções de tabela definidas pelo usuário (UDTFs) do Python

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

Considerações sobre o desempenho

  • As funções integradas e os UDFs do siteSQL são a opção mais eficiente disponível.

  • Em geral, os UDFs do Scala são mais rápidos, pois são executados dentro da Java Virtual Machine (JVM) e evitam a sobrecarga de mover dados para dentro e para fora da JVM.

  • Os UDFs do Python e do Pandas tendem a ser mais lentos do que os UDFs do Scala porque exigem que os dados sejam serializados e movidos para fora da JVM para o interpretador do Python. As UDFs do Pandas são até 100 vezes mais rápidas do que as UDFs do Python porque usam o Apache Arrow para reduzir os custos de serialização.