在DataFrame中使用UDF

时间:2018-07-19 11:44:56

标签: scala apache-spark user-defined-functions

我有一个数据框dfmmmIncOther:

 dfmmmIncOther=dfmmmIncOther.agg(max("time_res"),min("time_res"),avg("time_res")).withColumn("typestat",lit("IQ_SU5"))
        .withColumnRenamed("max(time_res)","delay max")
        .withColumnRenamed("min(time_res)","delay min")
        .withColumnRenamed("avg(time_res)","delay moy") 

time_res的类型是一分钟

我做了一个将分钟转换为小时的函数,然后将其转换为UDF以在以下时间使用它:

//在udf上转换小时数

 val convertHours : (Int) => String =(input: Int) => {
      val minutes = input%60
      val hours   = input/60
      "%sh:%sm".format(hours,minutes)
    }

    val udfconvertHours = udf(convertHours)*

我将变量dfmmmIncOther更改为将分钟转换为小时:

dfmmmIncOther=dfmmmIncOther.withColumn("delaymax",udfconvertHours(col("delay max"))).withColumn("delaymin",udfconvertHours(col("delay min"))).withColumn("delaymoy",udfconvertHours(col("delay moy")))

spark解释器返回一个大异常,我认为我的语法错误,但不知道确切的位置。

您的一些评论,我将不胜感激

1 个答案:

答案 0 :(得分:2)

您做错的主要事情之一是重新分配变量dfmmmIncOther

您可以使用新变量来存储它,而不是重新分配它

这是简单的示例

import spark.implicits._

//sample data 
val dfmmmIncOther = Seq(120, 122, 12, 68, 123, 435, 234).toDF("time_res")

//create an UDF 
val udfconvertHours = udf((input: Int) => "%sh:%sm".format(input/60,input%60))

//calculate and apply udf
var result = dfmmmIncOther.agg(
  max("time_res").as("max"),
  min("time_res").as("min"),
  avg("time_res").as("avg")
  )
  .withColumn("typestat", lit("IQ_SU5"))
  .withColumn("delaymax",udfconvertHours(col("max")))
  .withColumn("delaymin",udfconvertHours(col("min")))
  .withColumn("delaymoy",udfconvertHours(col("avg")))

result.show(false)

输出:

+---+---+------------------+--------+--------+--------+--------+
|max|min|avg               |typestat|delaymax|delaymin|delaymoy|
+---+---+------------------+--------+--------+--------+--------+
|435|12 |159.14285714285714|IQ_SU5  |7h:15m  |0h:12m  |2h:39m  |
+---+---+------------------+--------+--------+--------+--------+