spark add_month无法按预期工作

时间:2017-11-03 15:28:37

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

在数据框中,我正在生成一个基于日期类型格式为“yyyy-MM-dd”的列A的列。 A列是从UDF生成的(udf生成过去24个月的随机日期)。

从该生成日期开始,我尝试计算B列.B列是A列减去6个月。恩。 2017-06-01在A中是2017-01-01在B. 为了实现这一点,我使用函数add_months(columname,-6)

当我使用另一列(不是由udf生成)时,我得到了正确的结果。但是当我在生成的列上执行此操作时,我会得到随机值,完全错误。

我检查了架构,列来自DateType

这是我的代码:

val test = df.withColumn("A", to_date(callUDF("randomUDF")))
val test2 = test.select(col("*"), add_months(col("A"), -6).as("B"))

我的UDF代码:

sqlContext.udf.register("randomUDF", () => {

//prepare dateformat
val formatter = new SimpleDateFormat("yyyy-MM-dd")

//get today's date as reference 
val today = Calendar.getInstance()
val now = today.getTime()

//set "from" 2 years from now
val from = Calendar.getInstance()
from.setTime(now)
from.add(Calendar.MONTH, -24)

// set dates into Long
val valuefrom = from.getTimeInMillis()
val valueto = today.getTimeInMillis()

//generate random Long between from and to
val value3 = (valuefrom + Math.random()*(valueto - valuefrom))

// set generated value to Calendar and format date
val calendar3 = Calendar.getInstance()
calendar3.setTimeInMillis(value3.toLong)
formatter.format(calendar3.getTime()
}

UDF按预期工作,但我认为这里出了问题。 我在另一列(未生成)上尝试了add_months函数,它运行正常。

我使用此代码获得的结果示例:

A            |      B
2017-10-20   |   2016-02-27
2016-05-06   |   2015-05-25
2016-01-09   |   2016-03-14
2016-01-04   |   2017-04-26

使用spark版本1.5.1 使用scala 2.10.4

1 个答案:

答案 0 :(得分:0)

在您的代码中创建test2 dataframe

val test2 = test.select(col("*"), add_months(col("A"), -6).as("B"))

spark视为

val test2 = df.withColumn("A", to_date(callUDF("randomUDF"))).select(col("*"), add_months(to_date(callUDF("randomUDF")), -6).as("B"))

因此,您可以看到udf函数被调用两次。 df.withColumn("A", to_date(callUDF("randomUDF")))正在生成column A中的日期。 add_months(to_date(callUDF("randomUDF")), -6).as("B")再次调用udf函数并生成新日期并从中减去6个月并在column B中显示该日期。

这就是你得到随机日期的原因。

解决方法是在persist cache中使用testdataframe作为

val test = df.withColumn("A", callUDF("randomUDF")).cache()
val test2 = test.as("table").withColumn("B", add_months($"table.A", -6))