我不相信您可以将DateTimeFormatter 作为参数传递给UDF。您只能传入Column。一种解决方案是:
val return_date = udf((str: String, format: String) => {
DateTimeFormat.forPatten(format).formatted(str))
})
然后:
val user_with_dates_formatted = users.withColumn(
"formatted_date",
return_date(users("ordering_date"), lit("yyyy/MM/dd"))
)
不过,老实说——这和你原来的算法都有同样的问题。他们都使用forPattern 解析yyyy/MM/dd 来处理每条记录。最好是创建一个包裹在Map[String,DateTimeFormatter] 周围的单例对象,可能像这样(完全未经测试,但你明白了):
object DateFormatters {
var formatters = Map[String,DateTimeFormatter]()
def getFormatter(format: String) : DateTimeFormatter = {
if (formatters.get(format).isEmpty) {
formatters = formatters + (format -> DateTimeFormat.forPattern(format))
}
formatters.get(format).get
}
}
然后您将UDF 更改为:
val return_date = udf((str: String, format: String) => {
DateFormatters.getFormatter(format).formatted(str))
})
这样,DateTimeFormat.forPattern(...) 每个执行程序的每个格式只调用一次。
关于单例对象解决方案需要注意的一点是,您不能在 spark-shell 中定义对象——您必须将其打包到 JAR 文件中并使用 --jars 选项到 spark-shell 如果你想在 shell 中使用 DateFormatters 对象。