2017-07-27 51 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 
相关问题