Python 在pyspark数据帧中将重叠间隔列表拆分为非重叠子间隔,并检查重叠间隔上的值是否有效

Python 在pyspark数据帧中将重叠间隔列表拆分为非重叠子间隔,并检查重叠间隔上的值是否有效,python,apache-spark,pyspark,apache-spark-sql,Python,Apache Spark,Pyspark,Apache Spark Sql,我有一个pyspark数据框,其中包含定义每行间隔的列start\u time,end\u time。如果一个间隔至少与另一个间隔重叠,则它还包含一个列被复制设置为True;如果不是,则设置为False 有一个列rate,我想知道子间隔是否有不同的值(定义重叠);如果是这样,我想保留updated\u列中包含最新更新的记录作为基本事实 在中间步骤中,我想创建一列is\u validated设置为: None子间隔不重叠时 True当子间隔与另一个包含不同速率值的子间隔重叠并且是最后一次更新时

我有一个pyspark数据框,其中包含定义每行间隔的列
start\u time
end\u time
。如果一个间隔至少与另一个间隔重叠,则它还包含一个列
被复制
设置为
True
;如果不是,则设置为
False

有一个列
rate
,我想知道子间隔是否有不同的值(定义重叠);如果是这样,我想保留
updated\u列中包含最新更新的记录作为基本事实

在中间步骤中,我想创建一列
is\u validated
设置为:

  • None
    子间隔不重叠时
  • True
    当子间隔与另一个包含不同
    速率
    值的子间隔重叠并且是最后一次更新时
  • False
    当子间隔与另一个子间隔重叠时,该子间隔包含不同的
    速率
    值,并且不是上次更新的子间隔
注意:中间步骤不是强制性的,我提供它只是为了让解释更清楚

输入:

#因此:
输入行=[行(开始时间='2018-01-01 00:00:00',结束时间='2018-01-04 00:00:00',速率=10,更新时间='2021-02-25 00:00:00'),#重叠:(1,4)和(2,3)和(3,5),速率=10/20
行(开始时间='2018-01-02 00:00:00',结束时间='2018-01-03 00:00:00',费率=10,更新时间='2021-02-25 00:00:00'),#重叠:与(1,4)完全重叠的(2,3)
行(开始时间为2018-01-03 00:00:00',结束时间为2018-01-05 00:00:00',费率=20,更新时间为2021-02-20 00:00:00',重叠:(3,5)和(1,4),费率=10/20
世界其他地区(开始时间为2018-01-06 00:00:00',结束时间为2018-01-07 00:00:00',费率为30,更新时间为2021-02-25 00:00:00',无重叠:在(5,6)之间的孔
世界其他地区(开始时间为2018-01-07 00:00:00',结束时间为2018-01-08 00:00:00',费率为30,更新时间为2021-02-25 00:00:00')。#无重叠
df=spark.createDataFrame(输入行)
df.show()
>>> +-------------------+-------------------+----+-------------------+
|开始时间|结束时间|速率|更新时间||
+-------------------+-------------------+----+-------------------+
|2018-01-01 00:00:00|2018-01-04 00:00:00|  10|2021-02-25 00:00:00|
|2018-01-02 00:00:00|2018-01-03 00:00:00|  10|2021-02-25 00:00:00|
|2018-01-03 00:00:00|2018-01-05 00:00:00|  20|2021-02-20 00:00:00|
|2018-01-06 00:00:00|2018-01-07 00:00:00|  30|2021-02-25 00:00:00|
|2018-01-07 00:00:00|2018-01-08 00:00:00|  30|2021-02-25 00:00:00|
+-------------------+-------------------+----+-------------------+
#将成为:
tmp_行=[行(开始时间='2018-01-01 00:00:00',结束时间='2018-01-02 00:00:00',速率=10,更新时间='2021-02-25 00:00:00',是否重复=假,是否验证=无),
行(开始时间=2018-01-02 00:00:00',结束时间=2018-01-03 00:00:00',速率=10,更新时间=2021-02-25 00:00:00',是否重复=真,是否验证=真),
行(开始时间=2018-01-02 00:00:00',结束时间=2018-01-03 00:00:00',速率=10,更新时间=2021-02-25 00:00:00',是否重复=真,是否验证=真),
行(开始时间=2018-01-03 00:00:00',结束时间=2018-01-04 00:00:00',速率=10,更新时间=2021-02-20 00:00:00',是否重复=真,是否验证=假),
行(开始时间=2018-01-03 00:00:00',结束时间=2018-01-04 00:00:00',速率=20,更新时间=2021-02-25 00:00:00',是否重复=真,是否验证=真),
行(开始时间=2018-01-04 00:00:00',结束时间=2018-01-05 00:00:00',费率=20,更新时间=2021-02-25 00:00:00',是否重复=错误,是否验证=无),
行(开始时间=2018-01-06 00:00:00',结束时间=2018-01-07 00:00:00',费率=30,更新时间=2021-02-25 00:00:00',是否重复=假,是否验证=无),
行(开始时间=2018-01-07 00:00:00',结束时间=2018-01-08 00:00:00',费率=30,更新时间=2021-02-25 00:00:00',是否重复=假,是否验证=无)
]
tmp_df=spark.createDataFrame(tmp_行)
tmp_df.show()
>>> 
+-------------------+-------------------+----+-------------------+-------------+------------+
|开始|结束|时间|速率|更新|是否重复|是否验证|
+-------------------+-------------------+----+-------------------+-------------+------------+
|2018-01-01 00:00:00 | 2018-01-02 00:00:00 | 10 | 2021-02-25 00:00:00 |假|空|
|2018-01-02 00:00:00 | 2018-01-03 00:00:00 | 10 | 2021-02-25 00:00:00 |对|对|
|2018-01-02 00:00:00 | 2018-01-03 00:00:00 | 10 | 2021-02-25 00:00:00 |对|对|
|2018-01-03 00:00:00 | 2018-01-04 00:00:00 | 10 | 2021-02-20 00:00:00 |真|假|
|2018-01-03 00:00:00 | 2018-01-04 00:00:00 | 20 | 2021-02-25 00:00:00 |对|对|
|2018-01-04 00:00:00 | 2018-01-05 00:00:00 | 20 | 2021-02-25 00:00:00 |假|空|
|2018-01-06 00:00:00 | 2018-01-07 00:00:00 | 30 | 2021-02-25 00:00:00 |假|空|
|2018-01-07 00:00:00 | 2018-01-08 00:00:00 | 30 | 2021-02-25 00:00:00 |假|空|
+-------------------+-------------------+----+-------------------+-------------+------------+
#给你:
输出行=[行(开始时间='2018-01-01 00:00:00',结束时间='2018-01-02 00:00:00',速率=10),
世界其他地区(开始时间=2018-01-02 00:00:00',结束时间=2018-01-03 00:00:00',费率=10),
世界其他地区(开始时间=2018-01-03 00:00:00',结束时间=2018-01-04 00:00:00',费率=20),
世界其他地区(开始时间=2018-01-04 00:00:00',结束时间=2018-01-05 00:00:00',费率=20
import pyspark.sql.functions as F

output = df.selectExpr(
    """
    inline(arrays_zip(
        sequence(timestamp(start_time), timestamp(end_time) - interval 1 day, interval 1 day),
        sequence(timestamp(start_time) + interval 1 day, timestamp(end_time), interval 1 day)
    )) as (start_time, end_time)
    """,
    "rate", "updated_at"
).groupBy(
    'start_time', 'end_time'
).agg(
    F.max(F.struct('updated_at', 'rate'))['rate'].alias('rate')
).orderBy("start_time")

output.show()
+-------------------+-------------------+----+
|         start_time|           end_time|rate|
+-------------------+-------------------+----+
|2018-01-01 00:00:00|2018-01-02 00:00:00|  10|
|2018-01-02 00:00:00|2018-01-03 00:00:00|  10|
|2018-01-03 00:00:00|2018-01-04 00:00:00|  10|
|2018-01-04 00:00:00|2018-01-05 00:00:00|  20|
|2018-01-06 00:00:00|2018-01-07 00:00:00|  30|
|2018-01-07 00:00:00|2018-01-08 00:00:00|  30|
+-------------------+-------------------+----+