我正在使用Spark 1.3。我想做一些基于日期的计算。在以下数据集中,对于每个唯一ID,我想获取beging_date最大的记录(最新记录)。
另外,当我从文件中读取数据时,是否应该将其转换为TimestampType(import org.apache.spark.sql.types.TimestampType)?
以下是一些示例数据:
id beging_date end_date
1 1/1/2016 20:06:00.0 1/4/2016 20:06:00.0
2 1/5/2013 20:06:00.0 1/8/2016 20:06:00.0
1 1/6/2013 20:06:00.0 1/18/2016 20:06:00.0
3 2/1/2013 20:06:00.0 2/5/2016 20:06:00.0
1 1/20/2013 20:06:00.0 2/4/2016 20:06:00.0
3 3/5/2013 20:06:00.0 3/8/2016 20:06:00.0
这是所需的输出:
id beging_date end_date
1 1/20/2013 20:06:00.0 2/4/2016 20:06:00.0
2 1/5/2013 20:06:00.0 1/8/2016 20:06:00.0
3 3/5/2013 20:06:00.0 3/8/2016 20:06:00.0
答案 0 :(得分:1)
在处理日期时,我认为分别谈论数据如何存储在磁盘或序列化以及如何将其作为对象存储在内存中非常重要。
您的日期序列化为字符串。字符串表示是一种非常差的表示;它可能是TimestampType
,LongType
,甚至DoubleType
背后的第四选择。解析字符串总是很痛苦。另一方面 - 您的日期已经被序列化为字符串,您是否需要/想要更改它?
我会考虑保留原始列,并创建一个更有利于数据修改的新列。
这引出了我的下一点 - 你想如何将日期表示为内存中的对象,完全打开了你想要如何使用它的方式。对于像“找到最大值”这样的操作,最简单的可能是将其转换为LongType
- 例如1970年1月1日以来的毫秒数。几乎每个与日期相关的对象和函数都可以摄取或吐出unix
时间戳,因此它们很容易来回转换。
要将字符串转换为TimestampType
,您需要将其转换为java.sql.Timestamp
。我会留给你弄清楚确切的格式,但你需要类似的东西:
import java.sql.Timestamp
import java.text.SimpleDateFormat
val formatter = new SimpleDateFormat(...)
val millis_since_1_1_1970 = formatter.parse("1/5/2013 20:06:00.0").getTime
val timestamp = new java.sql.Timestamp(millis_since_1_1_1970)
就像我说的那样,您可以在millis_since_1_1_1970
之后停止并使用Long
值作为比较值。为了您的目的,它会起作用