ユーザー定義関数 (UDF) とは何ですか?

ユーザー定義関数 (UDF) を使用すると、Databricks の組み込み機能を拡張するコードを再利用および共有できます。 UDFs を使用して、複雑な計算、変換、カスタムデータ操作などの特定のタスクを実行します。

共有アクセス モードのクラスターでは、Python スカラー UDF は Databricks Runtime 14.1 以降でサポートされ、Scala UDF は Databricks Runtime 14.2 以降でサポートされます。

Python スカラー UDF は、Databricks Runtime 14.1 以降の SQL 構文を使用して Unity Catalog に登録できます。 「Unity Catalog のユーザー定義関数 (UDF)」を参照してください。

どのような場合に UDF を使用する必要がありますか?

UDFs は、組み込みの Apache Spark 関数では表現しにくいロジックに使用します。 組み込みの Apache Spark 関数は、分散処理用に最適化されており、一般に、大規模でより優れたパフォーマンスを提供します。 詳細については、「 関数」を参照してください。

Databricks では、アドホック クエリ、手動データクレンジング、探索的データ分析、および小規模から中規模のデータセットに対する操作に UDF を推奨しています。 UDF の一般的なユースケースには、データの暗号化と復号化、ハッシュ化、JSON 解析、検証などがあります。

Apache Spark メソッドは、非常に大規模なデータセットや、ETL ジョブやストリーミング操作など、定期的または継続的に実行されるワークロードに対する操作に使用します。

登録済みおよびセッション スコープの UDF

SQL を使用して作成された UDF は Unity Catalog に登録され、アクセス許可が関連付けられていますが、ノートブック内で作成された UDF はセッションベースであり、現在の SparkSession にスコープが設定されます。

セッションベースの UDF は、Databricks でサポートされている任意の言語を使用して定義し、アクセスできます。 UDF は、スカラーまたは非スカラーにすることができます。

現在、DBSQL で使用できるのは、Unity Catalog に登録されている SQL と Python のスカラー UDF のみです。

スカラー UDF

スカラー UDF は 1 つの行で動作し、各行に対して 1 つの値を返します。 次の例では、スカラー UDF を使用して、 name 列の各名前の長さを計算し、新しい列 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      |
+-------+-------+-------------+

これを PySpark を使用して Databricks ノートブックに実装するには、次のようにします。

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)

詳細については、Unity Catalogのユーザー定義関数 (UDFs) およびユーザー定義スカラー関数 - Pythonを参照してください。

ユーザー定義の集計関数 (UDAFs)

ユーザー定義の集計関数 (UDAFs) は、複数の行を操作し、1 つの集計結果を返します。 次の例では、スコアを集計する UDAF が定義されています。

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

PandasPythonのユーザー定義関数Scala および ユーザー定義集計関数 - を参照してください。

Python ユーザー定義テーブル関数 (UDTF)

プレビュー

この機能はパブリックプレビュー段階です。

Python UDTF は、Databricks Runtime 14.3 LTS 以降で使用できます。

Python ユーザー定義テーブル関数 (UDTF) は、入力行ごとに複数の行と列を返すことができます。 次の例では、score 列の各値がカテゴリのリストに対応しています。 UDTF は、コンマ区切りのリストを複数の行に分割するために定義されます。 Python ユーザー定義テーブル関数 (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    |
+-------+-------+----------+

パフォーマンスに関する考慮事項

  • 組み込み関数 SQL UDF は、利用可能な最も効率的なオプションです。

  • Scala UDFs は、Java 仮想マシン (JVM) 内で実行され、JVM との間でデータを移動するオーバーヘッドを回避するため、一般的に高速です。

  • Python UDFsPandas UDF は、データをシリアル化して JVM から Python インタープリターに移動する必要があるため、Scala UDFs よりも遅くなる傾向があります。 Pandas UDFs は、Apache Arrowを使用してシリアル化コストを削減するため、Python UDFsよりも最大100倍高速です。