将浮点列添加到时间戳类型列(秒+毫秒)
Posted
技术标签:
【中文标题】将浮点列添加到时间戳类型列(秒+毫秒)【英文标题】:Adding float column to TimestampType column (seconds+miliseconds) 【发布时间】:2021-07-07 17:41:47 【问题描述】:我正在尝试将浮点列添加到 pyspark 中的 TimestampType 列,但似乎没有办法在保持小数秒的同时做到这一点。 float_seconds 示例为 19.702300786972046,时间戳示例为 2021-06-17 04:31:32.48761
我想要什么:
calculated_df = beginning_df.withColumn("calculated_column", float_seconds_col + TimestampType_col)
我尝试了以下方法,但都没有完全解决问题:
#method 1 添加单个时间,但不能用于将整列添加到时间戳列。
calculated_df = beginning_df.withColumn("calculated_column",col("TimestampType_col") + F.expr('INTERVAL 19.702300786 seconds'))
#method 2 将 float 列转换为 unixtime,但去掉小数(这很重要)
timestamp_seconds = beginning_df.select(from_unixtime("float_seconds"))
Image of the two columns in question
【问题讨论】:
如果以下答案有帮助,请告诉我 根据您的示例,预期的结果是什么。是2021-06-17 04:31:52.189911
【参考方案1】:
您可以使用 UDF 来实现它,如下所示:
from datetime import datetime, timedelta
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, udf
from pyspark.sql.types import StructType, StructField, FloatType, TimestampType
spark = SparkSession \
.builder \
.appName("StructuredStreamTesting") \
.getOrCreate()
schema = (StructType([
StructField('dt', TimestampType(), nullable=True),
StructField('sec', FloatType(), nullable=True),
]))
item1 =
"dt": datetime.fromtimestamp(1611859271.516),
"sec": 19.702300786,
item2 =
"dt": datetime.fromtimestamp(1611859271.517),
"sec": 19.702300787,
item3 =
"dt": datetime.fromtimestamp(1611859271.518),
"sec": 19.702300788,
df = spark.createDataFrame([item1, item2, item3], schema=schema)
df.printSchema()
@udf(returnType=TimestampType())
def add_time(dt, sec):
return dt + timedelta(seconds=sec)
df = df.withColumn("new_dt", add_time(col("dt"), col("sec")))
df.printSchema()
df.show(truncate=False)
【讨论】:
谢谢!这是否可以扩展到非常大的数据集? IMO,这应该是可扩展的,你也可以运行分析。【参考方案2】:时间戳数据类型支持纳秒(最大 9 位精度)。您的 float_seconds_col 的精度 > 9 位(在您的示例中为 15,它是飞秒),无论如何转换为 Timestamp 都会丢失。
普通香草蜂巢:
select
timestamp(cast(concat(cast(unix_timestamp(TimestampType_col) as string), --seconds
'.',
regexp_extract(TimestampType_col,'\\.(\\d+)$')) --fractional
as decimal (30, 15)
) + float_seconds_col --round this value to nanos to get better timestamp conversion (round(float_seconds_col,9))
) as result --max precision is 9 (nanoseconds)
from
(
select 19.702300786972046 float_seconds_col,
timestamp('2021-06-17 04:31:32.48761') TimestampType_col
) s
结果:
2021-06-17 04:31:52.189910786
【讨论】:
@elfriend 如果可行,请接受/投票以上是关于将浮点列添加到时间戳类型列(秒+毫秒)的主要内容,如果未能解决你的问题,请参考以下文章