apache-spark - 如何在 Spark SQL 中将时间戳列转换为毫秒长列
问题描述
Timestamp
Spark SQL中将列转换为毫秒时间戳列的最短和最有效的方法是Long
什么?
这是从时间戳到毫秒的转换示例
scala> val ts = spark.sql("SELECT now() as ts")
ts: org.apache.spark.sql.DataFrame = [ts: timestamp]
scala> ts.show(false)
+-----------------------+
|ts |
+-----------------------+
|2019-06-18 12:32:02.41 |
+-----------------------+
scala> val tss = ts.selectExpr(
| "ts",
| "BIGINT(ts) as seconds_ts",
| "BIGINT(ts) * 1000 + BIGINT(date_format(ts, 'SSS')) as millis_ts"
| )
tss: org.apache.spark.sql.DataFrame = [ts: timestamp, seconds_ts: bigint ... 1 more field]
scala> tss.show(false)
+----------------------+----------+-------------+
|ts |seconds_ts|millis_ts |
+----------------------+----------+-------------+
|2019-06-18 12:32:02.41|1560861122|1560861122410|
+----------------------+----------+-------------+
如您所见,从时间戳获取毫秒的最直接方法不起作用 - 转换为长返回秒,但是时间戳中的毫秒信息被保留。
我发现提取毫秒信息的唯一方法是使用date_format
function ,这并不像我想象的那么简单。
有人知道从Timestamp
列中获得毫秒 UNIX 时间的方法比这更简单吗?
解决方案
根据 Spark 的DateTimeUtils上的代码:
“时间戳对外暴露为
java.sql.Timestamp
,内部存储为longs
,能够以微秒级精度存储时间戳。”
因此,如果您定义一个具有 ajava.sql.Timestamp
作为输入的 UDF,您可以简单地getTime
以毫秒为单位调用 Long。
val tsConversionToLongUdf = udf((ts: java.sql.Timestamp) => ts.getTime)
将此应用于各种时间戳:
val df = Seq("2017-01-18 11:00:00.000", "2017-01-18 11:00:00.111", "2017-01-18 11:00:00.110", "2017-01-18 11:00:00.100")
.toDF("timestampString")
.withColumn("timestamp", to_timestamp(col("timestampString")))
.withColumn("timestampConversionToLong", tsConversionToLongUdf(col("timestamp")))
.withColumn("timestampCastAsLong", col("timestamp").cast(LongType))
df.printSchema()
df.show(false)
// returns
root
|-- timestampString: string (nullable = true)
|-- timestamp: timestamp (nullable = true)
|-- timestampConversionToLong: long (nullable = false)
|-- timestampCastAsLong: long (nullable = true)
+-----------------------+-----------------------+-------------------------+-------------------+
|timestampString |timestamp |timestampConversionToLong|timestampCastAsLong|
+-----------------------+-----------------------+-------------------------+-------------------+
|2017-01-18 11:00:00.000|2017-01-18 11:00:00 |1484733600000 |1484733600 |
|2017-01-18 11:00:00.111|2017-01-18 11:00:00.111|1484733600111 |1484733600 |
|2017-01-18 11:00:00.110|2017-01-18 11:00:00.11 |1484733600110 |1484733600 |
|2017-01-18 11:00:00.100|2017-01-18 11:00:00.1 |1484733600100 |1484733600 |
+-----------------------+-----------------------+-------------------------+-------------------+
请注意,“timestampCastAsLong”列仅显示直接转换为 aLong
不会以毫秒为单位返回所需的结果,而只会以秒为单位。
推荐阅读
- java - Netbeans 11.2 的 Build > Compiling 窗格中没有“Additional Compiler Options”
- javascript - Promise All 在第一次 Promise 后卡住
- angular7 - 当我设置延迟加载时,为什么我的 Angular 7 应用程序不会在根路由中呈现任何内容?
- r - 绘制多个箱线图时如何使用 x 的特定离散值
- reactjs - 使用 async/await 更新 react-native 状态
- javascript - 修改 localStorage 时 mapStateToProps 不更新道具
- ios - Swift -FirebaseDatabase how to count and iterate through children that are only keyIds?
- java - 尝试使用 JAVA 中可比较的接口对数组进行排序
- excel - 列表框选择变成文本框选择
- python - 创建所有特定长度的二进制值向量