Kullanıcı tanımlı işlevler - Python

Bu makale, Python Kullanıcı tanımlı işlev (UDF) örnekleri içerir. Bu, UDF SQL ' deki alt ifadelerin değerlendirme sırasıyla ilgili UDF 'Leri, UDF 'Leri çağırmayı ve uyarıları nasıl kaydedeceğinizi gösterir.

Bir işlevi UDF olarak kaydetme

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

Alternatif olarak, UDF 'nizin dönüş türünü ayarlayabilirsiniz. Varsayılan dönüş türü StringType .

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

Spark SQL 'da UDF 'yi çağırın

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

DataFrames ile UDF kullanma

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

Alternatif olarak, ek açıklama sözdizimini kullanarak aynı UDF 'yi bildirebilirsiniz:

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

Değerlendirme sırası ve null denetimi

Spark SQL (SQL ve dataframe ve Dataset apı dahil), alt ifadelerin değerlendirilme sırasını garanti etmez. Özellikle, bir operatör veya işlevin girişleri soldan sağa veya başka bir sabit sırada değerlendirilmemelidir. Örneğin, mantıksal AND ve OR ifadeleri soldan sağa "kısa devre dışı" semantiğe sahip değildir.

Bu nedenle, bu WHERE HAVING tür ifadeler ve yan tümceler sorgu iyileştirmesi ve planlaması sırasında yeniden sıralanabilir olduğundan, bu nedenle, Boolean ifadelerin yan etkileri veya değerlendirilme sırası ve ve yan tümcelerinin sırası. özellikle, bir udf null denetim için SQL ' de kısa devre oluşturma semantiğini kullanıyorsa, udf 'yi çağırmadan önce null denetiminin olacağını garanti etmez. Örneğin,

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

Bu WHERE yan tümce, null değerleri strlen filtrelemeden sonra UDF 'nin çağrılmasını garanti etmez.

Doğru null denetimi gerçekleştirmek için aşağıdakilerden birini yapmanızı öneririz:

  • UDF 'nin kendi içinde null durumunu algılayan ve null denetlemesi yapma
  • IF CASE WHEN Bir koşullu dalda null denetimi yapmak ve UDF 'yi çağırmak için veya ifadelerini kullanın
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