0

我有一个数据帧的数据与下面列使用WithColumn与外部功能

1)FILEFORMAT是以下所有列数据类型CSV 2)字符串

employeeid,pexpense,cexpense 

现在我需要建立一个新的数据帧其中有一个名为expense的新列,它是根据列pexpense,cexpense进行计算的。

棘手的部分是计算算法是不是我创建了一个UDF功能,但它是一个外部函数,需要从一个Java库,需要原始类型作为参数输入 - 在这种情况下pexpensecexpense - 计算新列所需的值。

函数签名是从外部Java罐子

public class MyJava 

{ 

    public Double calculateExpense(Double pexpense, Double cexpense) { 
     // calculation 
    } 

} 

所以,我怎么可以调用外部函数来创建一个新的计算列。我可以在Spark应用程序中将该外部函数注册为UDF吗?

+1

您可以编辑您的文章,并添加您的数据框(1)的模式(让大家看到列的*数据类型*)和(2)您正在讨论的方法的_signature_? –

+0

@TzachZohar我已更新帖子 – shiv455

+0

@TzachZohar我已更新帖子 – shiv455

回答

1

您可以创建类似于以下(斑竹使用Scala的REPL)的外部方法的UDF:

// From a Linux shell prompt: 

vi MyJava.java 
public class MyJava { 
    public Double calculateExpense(Double pexpense, Double cexpense) { 
     return pexpense + cexpense; 
    } 
} 
:wq 

javac MyJava.java 
jar -cvf MyJava.jar MyJava.class 

spark-shell --jars /path/to/jar/MyJava.jar 

// From within the Spark shell 

val df = Seq(
    ("1", "1.0", "2.0"), ("2", "3.0", "4.0") 
).toDF("employeeid", "pexpense", "cexpense") 

val myJava = new MyJava 

val myJavaUdf = udf(
    myJava.calculateExpense _ 
) 

val df2 = df.withColumn("totalexpense", myJavaUdf($"pexpense", $"cexpense")) 

df2.show 
+----------+--------+--------+------------+ 
|employeeid|pexpense|cexpense|totalexpense| 
+----------+--------+--------+------------+ 
|   1|  1.0|  2.0|   3.0| 
|   2|  3.0|  4.0|   7.0| 
+----------+--------+--------+------------+ 
+0

我即将发布相同的内容,但无论如何感谢您的答案! – shiv455

-1

波纹管,是总和的一个例子两列:

val somme= udf((a: Int, b: int) => a+b) 

val df_new = df.select(col("employeeid"), \ 
         col("pexpense"), \ 
         col("pexpense"), \ 
         somme(col("pexpense"), col("pexpense")) as "expense") 
+0

该函数是一个外部Java函数而不是我在我的应用程序中定义的UDF – shiv455

0

通过使其作为参数传递给该udf功能org.apache.spark.sql.functions可以简单地“包裹”在UDF给定方法:

import org.apache.spark.sql.functions._ 
import spark.implicits._ 

val myUdf = udf(calculateExpense _) 
val newDF = df.withColumn("expense", myUdf($"pexpense", $"cexpense")) 

此处假定pexpensecexpense列均为Double s。

+0

正如我所说calculateExpense是一个外部函数,它是一个名为MyJava .i需要实例化这个类并用对象引用调用它。..你的解决方案仍然有效吗? – shiv455

+0

(已离线) - 答案是肯定的,你只需要实例化一个MyJava实例并使用它来引用该方法,就像@ leo-c在类似的答案中显示的一样...... –