Spark中如何将values值与日期序列逐一映射关联?
问题描述
输入数据
| Id | FirstDate | LastDate | values |
|---|---|---|---|
| 1 | 2023-12-10 | 2023-12-14 | 2,4,6,7,8 |
| 2 | 2024-01-12 | 2023-12-21 | 0,0,16,2,7,0,1,1,2,3 |
期望输出
| Id | FirstDateAndLastDate | value |
|---|---|---|
| 1 | 2023-12-10 | 2 |
| 1 | 2023-12-11 | 4 |
| 1 | 2023-12-12 | 6 |
| 1 | 2023-12-13 | 7 |
| 1 | 2023-12-14 | 8 |
| 2 | 2024-01-12 | 0 |
| 2 | 2024-01-13 | 0 |
| 2 | 2024-01-14 | 16 |
| 2 | 2024-01-15 | 2 |
| 2 | 2024-01-16 | 7 |
| 2 | 2024-01-17 | 0 |
| 2 | 2024-01-18 | 1 |
| 2 | 2024-01-19 | 1 |
| 2 | 2024-01-20 | 2 |
| 2 | 2024-01-21 | 3 |
当前已能通过代码生成日期序列,也能拆分values字段,但无法将两者按位置一一关联:
df.withColumn("FirstDateAndLastDate", explode(expr("sequence(to_date(FirstDate), to_date(LastDate), interval 1 day)")))
df.withColumn("new_value", explode(split(col("values"), ",")))
解决方案
核心思路是先将日期序列和拆分后的values数组按索引配对,再炸开配对后的结构体数组,实现一一映射:
from pyspark.sql import functions as F from pyspark.sql.functions import expr # 1. 生成日期序列数组与values拆分后的数组,用arrays_zip按索引配对 # 2. 炸开配对后的结构体数组 # 3. 提取结构体中的日期和值字段,并重命名、转换类型 result_df = df.withColumn( "date_value_pair", expr("arrays_zip(sequence(to_date(FirstDate), greatest(to_date(FirstDate), to_date(LastDate)), interval 1 day), split(values, ','))") ).withColumn( "date_value_pair", F.explode("date_value_pair") ).select( "Id", F.col("date_value_pair.0").alias("FirstDateAndLastDate"), F.col("date_value_pair.1").cast("int").alias("value") ) result_df.show()
关键说明
arrays_zip:将两个数组按索引位置一一配对,生成包含日期和对应值的结构体数组greatest(to_date(FirstDate), to_date(LastDate)):处理输入中LastDate早于FirstDate的异常情况(如Id=2的输入),确保日期序列从较早的日期开始生成- 最后通过
select提取结构体中的字段,并将value转为整数类型(根据需求可选)
内容的提问来源于stack exchange,提问作者Sandesh
相关产品推荐
相关产品推荐

