如何使用Java UDF向Spark数据框添加新列

时间:2019-03-25 07:21:15

标签: apache-spark apache-spark-sql

我有一个Dataset<Row> inputDS,其中有4列,即Id, List<long> time, List<String> value, aggregateType,我想使用map函数在Dataset value_new的基础上再添加一列,该map函数采用{ {1}},timevalue将其传递给函数aggregateType,并在处理参数时返回一个双精度值。方法getAggregate(String aggregateType, List<long> time, List<String> value)返回的Double值将是新的列值,即getAggregate

数据集输入DS

value_new

预期的数据集输出DS

 +------+---+-----------+---------------------------------------------+---------------+
 |    Id| value         |     time                                   |aggregateType  |
 +------+---------------+---------------------------------------------+---------------+
 |0001  |  [1.5,3.4,4.5]| [1551502200000,1551502200000,1551502200000] | Sum           |
 +------+---------------+---------------------------------------------+---------------+

我尝试过的代码

 +------+---------------+---------------------------------------------+---------------+-----------+
 |    Id| value         |     time                                    |aggregateType  | value_new |
 +------+---------------+---------------------------------------------+---------------+-----------+
 |0001  |  [1.5,3.4,4.5]| [1551502200000,1551502200000,1551502200000] | Sum           |   9.4     |
 +------+---------------+---------------------------------------------+---------------+-----------+

错误

 inputDS.withColumn("value_new",functions.lit(inputDS.map(new MapFunction<Row,Double>(){

 public double call(Row row){
 String aggregateType = row.getAS("aggregateType");
 List<long> timeList = row.getList("time");
 List<long> valueList= row.getList("value");  

 return  getAggregate(aggregateType ,timeList,valueList);    

 }}),Encoders.DOUBLE())));

注意:很抱歉,如果我错误地使用了 Unsupported literal type class org.apache.spark.sql.Dataset [value:double] 函数,请问我是否有解决方法。

谢谢。!

1 个答案:

答案 0 :(得分:0)

出现错误是因为您试图使用lit()的结果创建函数文字(Dataset.map()),您可以在文档中看到的是数据集。您可以在Dataset.withColumn()的API中看到,您需要一个作为列的参数。

似乎您需要创建一个用户定义的函数。看看How do I call a UDF on a Spark DataFrame using JAVA?