我在pyspark中有一个UDF,如下所示,可以将字符串转换为时间戳
@udf(returnType=TimestampType())
def to_timestamp(dt):
return parse(dt)
TimestampType-从pyspark.sql.types导入TimestampType
我想将其转换为Scala(火花),我尝试如下所示,但未选择参数
def toTimestampFormat(dt: String): TimestampType= {
return unix_timestamp(dt, "yyyyMMdd'T'HHmmss:SSSSSS").cast(TimestampType)
}
我在其中缺少什么吗?
答案 0 :(得分:1)
您无需创建UDF即可将字符串转换为时间戳,只需通过调用unix_timestamp
方法使用Spark SQL中的with_column
函数即可:
dataframe.withColumn("timestamp", unix_timestamp($"date", "yyyyMMdd'T'HHmmss:SSSSSS"))
第一个参数是字符串格式的日期所在的列。第二个是该字符串的格式。
别忘了导入unix_timestamp
函数和Spark隐式函数以使用$
运算符:
import org.apache.spark.sql.functions.unix_timestamp
import spark.implicits._
希望有帮助!
如果您确信要在UDF中执行此操作,则不能使用其中的unix_timestamp
,因为它必须接收一个Spark列对象,并且在定义UDF时,您可以不要使用列对象,而是使用该列的实际值。这就是为什么
在您的代码中,unix_timestamp
没有选择参数。此外,您创建的用于定义UDF的函数必须返回Scala本机数据类型而不是Spark列数据类型,因此在此类函数中返回TimestampType
毫无意义。
要将字符串转换为UDF中的时间戳,您需要一个接受字符串并返回Long对象的函数。在此示例中,我通过使用Joda-Time Scala库来定义所需的UDF:
val toTimestampFormat = udf((dt: String) => {
val formatter = DateTimeFormat.forPattern("yyyyMMdd'T'HHmmss")
formatter.parseDateTime(dt).getMillis
})
最后,这就是您使用此UDF的方式:
dataframe.withColumn("timestamp", toTimestampFormat(col("date")))
如果您希望列数据类型为TimestampType
,则UDF中的函数必须返回一个java.sql.Timestamp
对象:
val toTimestampFormat = udf((dt: String) => {
val formatter = DateTimeFormat.forPattern("yyyyMMdd'T'HHmmss")
new Timestamp(formatter.parseDateTime(dt).getMillis)
})