2016-11-25 50 views
2

基本上我试图做的是使自己的IF函数但通用的返回类型是否可以登记具有通用返回类型Scala中的UDF

我想注册这个功能,所以我可以用一个数据帧

def myfunc[A] (cond : Boolean, condMet : A, condNotMet : A): A = { 
    if(cond) 
    return condMet; 
    else 
    return condNotMet; 

} 
val apply_func = udf(myfunc _); 
val xp = h.withColumn("myUDF", apply_func('values0,"met",false).show 

使用它,但我得到这个错误

<console>:100: error: type mismatch; 
found : (Boolean, Nothing, Nothing) => Nothing 
required: (Boolean, A2, A3) => RT 
     val apply_func = udf(myfunc _); 

我想知道如果我能真正注册该功能,或者如果不是做同样的其他功能已经存在,或也许这是不可能的。

我大多会发送字符串,布尔值,数字作为condMet和condNotMet。

+0

在您return'的'用法:https://stackoverflow.com/questions/12560463/return-in-scala/12560532 – Reactormonk

+0

在你的例子,新列的类型应该是什么? –

+0

我没有设置类型,它取决于具体的情况。这就是为什么我用它 –

回答

1

不知道这是可能的UDF的,但你可以下拉到RDD水平。例如:

def myfunc[A] (cond : Boolean, condMet : A, condNotMet : A): A = { 
    if(cond) 
    return condMet 
    else 
    return condNotMet 
} 

val test = sc.parallelize(Seq(1,2,3)) 
val res = test.map(r => myfunc(r == 1, 1, "B").getClass) 

现在水库为类,你也可以看到它们的类型的数组。看看如下:

res.take(3) 
res: Array[Class[_]] = Array(class java.lang.Integer, class java.lang.String, class java.lang.String) 
+0

挣扎然后你就可以回去使用.toDF一个数据框() – racso

0

DataFrame中的列必须具有某种类型。

虽然我不知道你这个例子中,你可以做这样的事情:

val df=sc.parallelize(Seq(0,1,2)).toDF("mycol") 

val xp = df.withColumn("myNewCol", 
     when($"mycol" === lit(1), lit("met")).otherwise(lit(999)) 
    ) 

新列,然后自动为字符串类型的列上创建。

使用你的UDF,你就必须做到这一点:

def myfunc[A] (cond : Boolean, condMet : A, condNotMet : A): A = { 
    if(cond) 
    return condMet 
    else 
    return condNotMet 

} 
val apply_func = udf(myfunc[String] _) 
val xp = df.withColumn("myUDF", apply_func($"myNewCol"===1,lit("met"),lit(999))) 
相关问题