الوظائف العددية المعرفة من قبل المستخدم - Python

تحتوي هذه المقالة على أمثلة لدالة Python المعرفة من قبل المستخدم (UDF). يوضح كيفية تسجيل UDFs، وكيفية استدعاء UDFs، ويوفر تحذيرات حول ترتيب تقييم التعبيرات الفرعية في Spark SQL.

في Databricks Runtime 14.0 وما فوق، يمكنك استخدام دالات الجدول المعرفة من قبل مستخدم Python (UDTFs) لتسجيل الدالات التي ترجع علاقات بأكملها بدلا من القيم العددية. راجع وظائف الجدول المعرفة من قبل المستخدم Python (UDTFs).

إشعار

في Databricks Runtime 12.2 LTS والإدناه، لا يتم دعم Python UDFs وPandas UDFs في كتالوج Unity على الحساب الذي يستخدم وضع الوصول المشترك. يتم دعم Python UDFs العددية وUDFs Pandas العددية في Databricks Runtime 13.3 LTS وما فوق لجميع أوضاع الوصول.

في Databricks Runtime 13.3 LTS وما فوق، يمكنك تسجيل Python UDFs العددية في كتالوج Unity باستخدام بناء جملة SQL. راجع الدالات المعرفة من قبل المستخدم (UDFs) في كتالوج Unity.

تسجيل دالة ك UDF

def squared(s):
  return s * s
spark.udf.register("squaredWithPython", squared)

يمكنك اختياريا تعيين نوع الإرجاع ل UDF الخاص بك. نوع الإرجاع الافتراضي هو StringType.

from pyspark.sql.types import LongType
def squared_typed(s):
  return s * s
spark.udf.register("squaredWithPython", squared_typed, LongType())

استدعاء UDF في Spark SQL

spark.range(1, 20).createOrReplaceTempView("test")
%sql select id, squaredWithPython(id) as id_squared from test

استخدام UDF مع DataFrames

from pyspark.sql.functions import udf
from pyspark.sql.types import LongType
squared_udf = udf(squared, LongType())
df = spark.table("test")
display(df.select("id", squared_udf("id").alias("id_squared")))

بدلا من ذلك، يمكنك الإعلان عن نفس UDF باستخدام بناء جملة التعليق التوضيحي:

from pyspark.sql.functions import udf
@udf("long")
def squared_udf(s):
  return s * s
df = spark.table("test")
display(df.select("id", squared_udf("id").alias("id_squared")))

ترتيب التقييم والتحقق من القيم الخالية

لا يضمن Spark SQL (بما في ذلك SQL وDataFrame وDataset API) ترتيب تقييم التعبيرات الفرعية. على وجه الخصوص، لا يتم بالضرورة تقييم مدخلات عامل التشغيل أو الدالة من اليسار إلى اليمين أو بأي ترتيب ثابت آخر. على سبيل المثال، لا تحتوي التعبيرات والمنطقية ANDOR على دلالات "دائرة قصيرة" من اليسار إلى اليمين.

لذلك، من الخطر الاعتماد على الآثار الجانبية أو ترتيب تقييم التعبيرات المنطقية، وترتيب WHERE العبارات و HAVING ، حيث يمكن إعادة ترتيب هذه التعبيرات والعبارات أثناء تحسين الاستعلام والتخطيط. على وجه التحديد، إذا كان UDF يعتمد على دلالات الدوائر القصيرة في SQL للتحقق من القيم الخالية، فلا يوجد ما يضمن أن التحقق من القيم الخالية سيحدث قبل استدعاء UDF. على سبيل المثال،

spark.udf.register("strlen", lambda s: len(s), "int")
spark.sql("select s from test1 where s is not null and strlen(s) > 1") # no guarantee

لا تضمن هذه WHERE العبارة strlen استدعاء UDF بعد تصفية القيم الخالية.

لإجراء فحص القيم الخالية المناسبة، نوصي بالقيام بأي مما يلي:

  • جعل UDF نفسه مدركا للقيم الخالية والقيام بالتحقق من القيم الخالية داخل UDF نفسه
  • استخدام IF أو CASE WHEN التعبيرات لإجراء فحص القيم الخالية واستدعاء UDF في فرع شرطي
spark.udf.register("strlen_nullsafe", lambda s: len(s) if not s is None else -1, "int")
spark.sql("select s from test1 where s is not null and strlen_nullsafe(s) > 1") // ok
spark.sql("select s from test1 where if(s is not null, strlen(s), null) > 1")   // ok