Spark

Remplacer une UDF Python par des fonctions natives

Une UDF Python sérialise chaque ligne vers un worker Python et aveugle Catalyst ; la même logique en fonctions natives reste optimisable et 10 à 100x plus rapide.

Cas d'usage

Revue de code : éliminer les UDF historiques d'un pipeline lent.

Prérequis

PySpark 3.x

Python
from pyspark.sql import functions as F

# AVANT : UDF ligne à ligne, opaque pour l'optimiseur
# @udf("string")
# def clean_phone(p):
#     return re.sub(r"[^0-9+]", "", p or "")[:15]

# APRÈS : équivalent 100 % natif, vectorisé côté JVM
df_clean = df.withColumn(
    "phone_clean",
    F.substring(
        F.regexp_replace(F.coalesce("phone", F.lit("")), "[^0-9+]", ""),
        1, 15,
    ),
)
# Check-list avant d'écrire une UDF : regexp_*, split, transform,
# aggregate, sequence, date_*, conv... couvrent l'immense majorité des cas.

Résultat

+--------------------+------------+
|               phone| phone_clean|
+--------------------+------------+
|+33 (0)6 12 34 56 78|+33612345678|
|      06-98-76-54-32|  0698765432|
|                null|            |
+--------------------+------------+

Sur 1.2 Md de lignes : UDF Python 312 s -> natif 9 s (x34)
PySparkUDFCatalystPerformance

Snippets liés

Retour au Data Lab