我有一个时间序列数据,我想以这样一种方式获取数据间隔:如果在检测器列中检测到1,那么它将是一个间隔的结束而另一个间隔的开始。我可以用groupby,但是我想使用一种替代方法,因为在使用groupby时会出现性能问题,并且如果两个连续行之间的时间差大于或等于15,则也要同时检测间隔。
为简单起见,我们可以举一个下面的例子
time | detector
5 | 0
10 | 0
15 | 0
20 | 0
25 | 1
35 | 0
40 | 0
56 | 0
57 | 0
55 | 0
60 | 1
65 | 0
70 | 0
75 | 0
80 | 1
85 | 0
我想要的输出是
interval
[5,25]
[25,60]
[40,56]
[60,80]
[80,85]
更新1:
val wAll = Window.partitionBy(col("imei")).orderBy(col("time").asc)
val test= df.withColumn("lead_time", lead("time", 1, null).over(wAll)).withColumn("runningTotal", sum("detector").over(wAll))
.groupBy("runningTotal").agg(struct(min("time"), max("lead_time")).as("interval"))
这是用于计算大于等于15分钟的数据点
val unreachable_df=df
.withColumn("lag_time",lag("time", 1, null).over(wAll))
.withColumn("diff_time",abs((col("time") - col("lag_time"))/60D))
.withColumn("unreachable",when(col("diff_time")>=15.0,0).otherwise(1))
.drop(col("diff_time"))
.drop(col("lag_time"))
.withColumn("runningTotal", sum("unreachable").over(wAll))
.groupBy("runningTotal")
.agg(struct(min("time"), max("time")).as("interval"))
.withColumn("diff_interval",abs((unix_timestamp(col("interval.col1"))-unix_timestamp(col("interval.col2")))))
.filter(col("diff_interval")>0) .drop("diff_interval")
.withColumn("type",lit("Unreachable")).drop("runningTotal")
然后我将两个数据框合并以获得上述结果
val merged_df=test.union(unreachable_df).sort(col("interval.col1"))