2017-07-27 23 views
0

我有蟒蛇星火這個用戶定義函數:如何將if-then表達式添加到用戶定義的函數中?

result = udf(lambda num1, num2: (num1 - num2)/math.sqrt(1-(num1/num2)), FloatType()) 

我想添加一個檢查num1/num2大於1。如果是低於1,則num1應等於num2

if (num1/num2 > 1): 
     num1 = num2 

如何將此簡單檢查添加到udf表達式中?

我想這一點,但它似乎失敗:

def calculate(num1, num2): 
    if (num1/num2 > 1): 
     num1 = num2 
    result = (num1 - num2)/math.sqrt(1-(num1/num2)) 
    return result 
calc_z = udf(lambda num1, num2: calculate, FloatType()) 
+2

udf(calculate,FloatType())'',不需要在'lambda'中錯誤地包裝它。 – deceze

回答

2

您可以使用其中的功能得到結果如下

df.withColumn("result", when(($"num1"/$"num2") < 1, $"num2") 
    .otherwise($"num1")) 

它總是更好地利用現有的功能,而不是使用UDF 。

如果你仍然想使用UDF您可以將上面的UDF註冊爲

calc_z = udf(calculate, FloatType()) 

希望這有助於!

+0

爲什麼使用'withColumn'而不是'udf'?它會影響計算時間嗎? – Dinosaurius

+0

是的,Spark將UDF視爲一個黑匣子,甚至不打算優化它。這裏是詳細信息https://jaceklaskowski.gitbooks.io/mastering-apache-spark/spark-sql-udfs.html –

1

您可以num1你的情況動態分配的,如果你將其替換num1

(num2 if num1/num2 > 1 else num1)

1

您需要的功能在lambda被調用。

def calculate(num1, num2): 
    if (num1/num2 > 1): 
     num1 = num2 
    result = (num1 - num2)/math.sqrt(1-(num1/num2)) 
    return result 
calc_z = udf(lambda num1, num2: calculate(num1, num2), FloatType()) 

不是最後一行調用計算的變化。

編輯(基於@bruno desthuilliers):

def calculate(num1, num2): 
    if (num1/num2 > 1): 
     num1 = num2 
    result = (num1 - num2)/math.sqrt(1-(num1/num2)) 
    return result 
calc_z = udf(calculate, FloatType()) 
+1

你根本不需要lambda - 只需要通過'calculate'作爲第一個參數。 –

+0

當我執行你的第二個代碼時,我得到這個錯誤IndentationError:unindent不匹配任何外部縮進級別。 – Dinosaurius

+0

檢查你的標籤和空格。並確保你的標籤是正確的。從網上覆制和粘貼代碼經常會弄亂縮進。 –

1

你拉姆達返回一個尚未被調用的函數。嘗試這個。

def calculate(num1, num2): 
    if (num1/num2 > 1): 
     num1 = num2 
    result = (num1 - num2)/math.sqrt(1-(num1/num2)) 
    return result 
calc_z = udf(calculate, FloatType()) # Changed this line 
相關問題