python - 计算跨数据帧的重叠时间间隔

标签 python pyspark

我正在尝试计算哪些行在时间上与 DataFrame 上的任何其他行重叠。给出这个例子:

            df = spark.createDataFrame(
            [
                [1,"2020:01:01 12:00", "2020:01:01 13:00"], # T
                [1,"2020:01:01 12:30", "2020:01:01 13:00"], # T
                [1,"2020:01:01 14:00", "2020:01:01 15:00"], # F
                [2,"2020:01:01 09:00", "2020:01:01 13:00"], # F
                [2,"2020:01:01 18:00", "2020:01:01 19:00"], # F
            ],
            ["id", "start", "end"]
        )
        w = Window.partitionBy("id").orderBy("start").rowsBetween(Window.unboundedPreceding, 0)
        df.withColumn("OVERLAPS", ?????.over(w)).show()

我想生成一个列,每当具有相同 id 的两行在时间上重叠时发出信号:

                [1,"2020:01:01 12:00", "2020:01:01 13:00", True], 
                [1,"2020:01:01 12:30", "2020:01:01 13:00", True], 
                [1,"2020:01:01 14:00", "2020:01:01 15:00", False], 
                [2,"2020:01:01 09:00", "2020:01:01 13:00", False], 
                [2,"2020:01:01 18:00", "2020:01:01 19:00", False],

理想情况下,我可以创建时间间隔,在 pandas 中它将使用 pd.IntervalIndex 并且我将有可以查询的间隔,例如 "2020:01:01 13:00 ” 在 [2020:01:01 12:30, 2020:01:01 14:00)

但我一直在努力在 Spark 上做到这一点。

最佳答案

所以我在 scala 中尝试了一下,但我的解决方案很丑陋,可能还可以改进(尤其是整个列重命名等)。我做了一个假设,即时间已经被解析为某种整数格式,然后我基本上用稍微复杂一点的连接解决了这个问题:

val s = Seq(
    (1, 1200, 1300),
    (1, 1230, 1300),
    (1, 1400, 1500),
    (2, 900, 1300),
    (2, 1800, 1900)
)

val df = s.toDF("id", "start", "end").withColumn("i", monotonicallyIncreasingId)
val dfr = df.select($"id", $"start".alias("start_r"), $"end".alias("end_r"), $"i".alias("i_r")) 

val overlaps = df.join(
    dfr,
    df("id") === dfr("id") 
        and df("start") <= dfr("end_r") 
        and df("end") >= dfr("start_r") 
        and (df("i") !== dfr("i_r"))
    ).select($"i".alias("i_overlaps"), lit(true).alias("overlaps"))

val result = df.join(overlaps, df("i") === overlaps("i_overlaps"), "left").
        drop("i_overlaps").
        withColumn("overlaps", when($"overlaps".isNull, false).otherwise($"overlaps"))

result.show

结果:

+---+-----+----+---+--------+                                                   
| id|start| end|  i|overlaps|
+---+-----+----+---+--------+
|  1| 1200|1300|  0|    true|
|  1| 1230|1300|  1|    true|
|  2|  900|1300|  3|   false|
|  1| 1400|1500|  2|   false|
|  2| 1800|1900|  4|   false|
+---+-----+----+---+--------+

您可以再次删除 i 列。在此解决方案中,根本不需要对数据帧进行重新分区或排序,因为这将在连接内处理。不过,这种类型的连接可能不是最有效的:)

关于python - 计算跨数据帧的重叠时间间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63842836/

相关文章:

python - 数据框中固定时间窗口的滚动平均值

python - Pandas:如何将虚线文本平面文件正确解析为数据框

python - 从具有不同长度值的字典生成多索引数据框

python - 通过 GroupBy.agg 和命名聚合计算加权平均值

apache-spark - 将数据框结果插入配置单元表时出现 Spark 异常

python - PySpark 正则表达式引擎不匹配

python - 如何计算pyspark数据框中一列中每个分类变量的频率?

Python加入日期和文件名

Python:如果存在空值,如何将 Pyspark 列转换为日期类型

arrays - Pyspark 数据框 : Count elements in array or list