我的数据集如下所示:(前三列是输入,我添加了第4-6列,最后一列代表了所需的输出)
+-------------------+------+----+-------------------+-------------------+-------------------+---+----+
| timestamp|status| msg| end_timestamp| start_eng| stop_eng| --|res |
+-------------------+------+----+-------------------+-------------------+-------------------+---+----+
|2017-01-01 06:15:00| ASC_a|nice|2017-01-01 07:00:00| null| null|-->| 0 |
|2017-01-01 07:00:00| ASC_a|nice|2017-01-01 07:15:00| null| null|-->| 0 |
|2017-01-01 07:15:00| start|nice|2017-01-01 08:00:00|2017-01-01 07:15:00| null|-->| 45 |
|2017-01-01 08:00:00| start|nice|2017-01-01 08:22:00|2017-01-01 08:00:00| null|-->| 22 |
|2017-01-01 08:22:00| ASC_b|init|2017-01-01 09:00:00| null| null|-->| 38 |
|2017-01-01 09:00:00| ASC_b|init|2017-01-01 09:30:00| null| null|-->| 30 |
|2017-01-01 09:30:00| end| bla|2017-01-01 10:00:00| null|2017-01-01 09:30:00|-->| 0 |
|2017-01-01 10:00:00| end| bla|2017-01-01 10:45:00| null|2017-01-01 10:00:00|-->| 0 |
|2017-01-01 10:45:00| ASC_a|meas|2017-01-01 11:00:00| null| null|-->| 0 |
|2017-01-01 11:00:00| ASC_a|meas|2017-01-01 12:00:00| null| null|-->| 0 |
|2017-01-01 12:00:00| ASC_a|meas|2017-01-01 12:15:00| null| null|-->| 0 |
|2017-01-01 12:15:00| start|meas|2017-01-01 13:00:00|2017-01-01 12:15:00| null|-->| 45 |
|2017-01-01 13:00:00| start|meas|2017-01-01 13:22:00|2017-01-01 13:00:00| null|-->| 22 |
|2017-01-01 13:22:00| ASC_c|init|2017-01-01 14:00:00| null| null|-->| 38 |
|2017-01-01 14:00:00| ASC_c|init|2017-01-01 14:31:00| null| null|-->| 31 |
|2017-01-01 14:31:00| end|meas| null| null|2017-01-01 14:31:00|-->| 0 |
+-------------------+------+----+-------------------+-------------------+-------------------+---+----+
我想计算从第一次出现状态开始到第一次出现状态结束时的引擎运行时间。 (状态开始和结束都出现在后续列中,因为我添加了具有explode功能的行,我以后仍然需要将它们更改为合理的值)
问题是我不知道如何计算开始和结束之间既不包含开始也不结束的行的引擎运行时。
我考虑过使用窗口函数进行计算,但我不知道如何为此指定窗口。
答案 0 :(得分:0)
我终于让它为小数据集工作了。还是要在大的那个上测试它。
//get tempstat column
val ds3 = ds2.withColumn("tempstat", when($"status".contains("ASC"), $"status").otherwise(null))
.withColumn("tempstat_final", last($"tempstat", true).over(window))
//remove duplicate status
val ds5 = ds3.withColumn("new_status", when(!$"status".contains("ASC") && lag($"status", 1).over(window) =!= $"status", $"status").otherwise($"tempstat_final"))
//get column that provides window for calculation
val ds6 = ds5.withColumn("startFlag", when($"new_status" === "start", 1).otherwise(0))
.withColumn("stopFlag", when($"new_status" === "end", -1).otherwise(0))
.withColumn("bothFlags", $"startFlag" + $"stopFlag")
.withColumn("engineFlag", sum($"bothFlags").over(Window.orderBy("timestamp")))
//calculate runtime
val ds7 = ds6.withColumn("runtime", when($"engineFlag" === 1,
((unix_timestamp(lead($"timestamp", 1).over(Window.orderBy($"timestamp"))) - unix_timestamp($"timestamp"))/60)
).otherwise(lit(0)))
输出和进展如下。
+-------------------+------+----+--------+--------------+----------+---------+--------+---------+----------+-------+
| timestamp|status| msg|tempstat|tempstat_final|new_status|startFlag|stopFlag|bothFlags|engineFlag|runtime|
+-------------------+------+----+--------+--------------+----------+---------+--------+---------+----------+-------+
|2017-01-01 06:15:00| ASC_a|nice| ASC_a| ASC_a| ASC_a| 0| 0| 0| 0| 0.0|
|2017-01-01 07:00:00| ASC_a|nice| ASC_a| ASC_a| ASC_a| 0| 0| 0| 0| 0.0|
|2017-01-01 07:15:00| start|nice| null| ASC_a| start| 1| 0| 1| 1| 45.0|
|2017-01-01 08:00:00| start|nice| null| ASC_a| ASC_a| 0| 0| 0| 1| 22.0|
|2017-01-01 08:22:00| ASC_b|init| ASC_b| ASC_b| ASC_b| 0| 0| 0| 1| 38.0|
|2017-01-01 09:00:00| ASC_b|init| ASC_b| ASC_b| ASC_b| 0| 0| 0| 1| 30.0|
|2017-01-01 09:30:00| end| bla| null| ASC_b| end| 0| -1| -1| 0| 0.0|
|2017-01-01 10:00:00| end| bla| null| ASC_b| ASC_b| 0| 0| 0| 0| 0.0|
|2017-01-01 10:45:00| ASC_a|meas| ASC_a| ASC_a| ASC_a| 0| 0| 0| 0| 0.0|
|2017-01-01 11:00:00| ASC_a|meas| ASC_a| ASC_a| ASC_a| 0| 0| 0| 0| 0.0|
|2017-01-01 12:00:00| ASC_a|meas| ASC_a| ASC_a| ASC_a| 0| 0| 0| 0| 0.0|
|2017-01-01 12:15:00| start|meas| null| ASC_a| start| 1| 0| 1| 1| 45.0|
|2017-01-01 13:00:00| start|meas| null| ASC_a| ASC_a| 0| 0| 0| 1| 60.0|
|2017-01-01 14:00:00| start|meas| null| ASC_a| ASC_a| 0| 0| 0| 1| 60.0|
|2017-01-01 15:00:00| start|meas| null| ASC_a| ASC_a| 0| 0| 0| 1| 22.0|
|2017-01-01 15:22:00| ASC_c|init| ASC_c| ASC_c| ASC_c| 0| 0| 0| 1| 38.0|
|2017-01-01 16:00:00| ASC_c|init| ASC_c| ASC_c| ASC_c| 0| 0| 0| 1| 31.0|
|2017-01-01 16:31:00| end|meas| null| ASC_c| end| 0| -1| -1| 0| 0.0|
+-------------------+------+----+--------+--------------+----------+---------+--------+---------+----------+-------++
我总是很乐意获得改进提示或其他解决方案提案,因为我还不熟悉spark / scala。