使用滑动时间检查值是否在阈值范围内 window/bins - KQL 查询

Check if value between a threshold range using sliding time window/bins - KQL query

我想在 KQL 中编写一个滑动 window 查询,它会检查汽车的速度是否始终在某个速度限制之间(例如 b/w 100 和 150 km/h) 时间 window 5 分钟。

以下是它的示例数据集:

Timestamp Speed Temperature
2022-01-01 00:00:00.0000000 142.5 25.1
2022-01-01 00:01:00.0000000 147.4 25.5
2022-01-01 00:02:00.0000000 158.2 25.4
2022-01-01 00:03:00.0000000 134.8 25.6
2022-01-01 00:04:00.0000000 125.3 25.5
2022-01-01 00:05:00.0000000 118.4 25.4
2022-01-01 00:06:00.0000000 106.3 26.3
2022-01-01 00:07:00.0000000 119.6 26.5
2022-01-01 00:08:00.0000000 134.7 25.4
2022-01-01 00:09:00.0000000 153.2 26.6
2022-01-01 00:10:00.0000000 137.5 25.5
2022-01-01 00:11:00.0000000 129.9 27.4
2022-01-01 00:12:00.0000000 118.1 26.3
2022-01-01 00:13:00.0000000 105.4 25.7
2022-01-01 00:14:00.0000000 101.7 24.4
2022-01-01 00:15:00.0000000 100.8 25.6
2022-01-01 00:16:00.0000000 95.4 26.2
2022-01-01 00:17:00.0000000 105.6 26.7

首先 window 将检查速度是否在定义的范围内,从 0-4 分钟,然后是 1-5 分钟,然后是 2-6 分钟,然后是 3-7 分钟,然后是 4-8 分钟,依此类推在 ..... 直到 10-14 分钟,然后是 11-15 分钟,然后是 12-16 分钟,然后是 13-17 分钟。如果速度连续在 100-150km/h 范围内,查询将 return 这些行作为输出。

我希望得到以下输出:

Timestamp Speed Temperature
2022-01-01 00:03:00.0000000 134.8 25.6
2022-01-01 00:04:00.0000000 125.3 25.5
2022-01-01 00:05:00.0000000 118.4 25.4
2022-01-01 00:06:00.0000000 106.3 26.3
2022-01-01 00:07:00.0000000 119.6 26.5
2022-01-01 00:08:00.0000000 134.7 25.4
2022-01-01 00:10:00.0000000 137.5 25.5
2022-01-01 00:11:00.0000000 129.9 27.4
2022-01-01 00:12:00.0000000 118.1 26.3
2022-01-01 00:13:00.0000000 105.4 25.7
2022-01-01 00:14:00.0000000 101.7 24.4
2022-01-01 00:15:00.0000000 100.8 25.6

在输出数据集中,0-2mins 的时间戳被过滤掉,因为当我们检查 0-4mins 时,有一个值 (158.2km/h) 超出范围 (100-150[=34=) ]).同样,我们在检查 1-5 分钟和检查 2-6 分钟时找到这个值。

从3-7分钟开始,所有速度值都在范围内持续5分钟。从 4-8 分钟开始,这就是保留这些行的原因。

最后,我只想绘制速度始终在范围内的所有 5 分钟时间 windows 的温度。绘图部分很清楚,所以我只需要过滤行的帮助。

提前致谢!

这是一个对您的数据没有任何假设的解决方案。
其他信息,例如时间戳的粒度,可能有助于简化它。

  1. 将行分成组,将速度为 out-of-range (OOR) 的记录作为边界。还要添加一个合成记录,以后可以用作最小边界。
  2. 为每个组找到其边界,这些边界与滑动间隔 (1m) 对齐。这里的主要挑战是找到每个组的下边界,因为对于上边界,我们使用 bin 这是 floor 的同义词,但我们没有 ceiling 的等价物。
  3. 删除小于定义window(5m)的组。
  4. 将组边界与组记录连接起来并删除 OOR 记录。

let p_sliding_interval = 1m;
let p_window = 5m;
let t = 
datatable (Timestamp:datetime ,Speed:real ,Temperature:real)
[
     '2022-01-01 00:00:00.0000000' ,142.5 ,25.1
    ,'2022-01-01 00:01:00.0000000' ,147.4 ,25.5
    ,'2022-01-01 00:02:00.0000000' ,158.2 ,25.4
    ,'2022-01-01 00:03:00.0000000' ,134.8 ,25.6
    ,'2022-01-01 00:04:00.0000000' ,125.3 ,25.5
    ,'2022-01-01 00:05:00.0000000' ,118.4 ,25.4
    ,'2022-01-01 00:06:00.0000000' ,106.3 ,26.3
    ,'2022-01-01 00:07:00.0000000' ,119.6 ,26.5
    ,'2022-01-01 00:08:00.0000000' ,134.7 ,25.4
    ,'2022-01-01 00:09:00.0000000' ,153.2 ,26.6
    ,'2022-01-01 00:10:00.0000000' ,137.5 ,25.5
    ,'2022-01-01 00:11:00.0000000' ,129.9 ,27.4
    ,'2022-01-01 00:12:00.0000000' ,118.1 ,26.3
    ,'2022-01-01 00:13:00.0000000' ,105.4 ,25.7
    ,'2022-01-01 00:14:00.0000000' ,101.7 ,24.4
    ,'2022-01-01 00:15:00.0000000' ,100.8 ,25.6
    ,'2022-01-01 00:16:00.0000000' ,95.4  ,26.2
    ,'2022-01-01 00:17:00.0000000' ,105.6 ,26.7
];
let min_Timestamp = toscalar(t | summarize min(Timestamp));
let max_Timestamp = toscalar(t | summarize max(Timestamp));
let row_level = 
t
| extend out_of_range_record_flag = iff(Speed !between (100 .. 150),1,0)
| union (print Timestamp = datetime(null) , out_of_range_record_flag = 1)
| order by Timestamp asc nulls first 
| extend in_range_group_id = row_cumsum(out_of_range_record_flag);
let group_boundries =
row_level 
| where out_of_range_record_flag == 1
| project in_range_group_id, from_timestamp = coalesce(Timestamp, min_Timestamp)
| order by in_range_group_id asc
| extend to_timestamp = coalesce(next(from_timestamp), max_Timestamp)
| extend bin_from_timestamp = bin(from_timestamp, p_sliding_interval)
| extend ceil_from_timestamp = bin_from_timestamp + iff(bin_from_timestamp == from_timestamp, 0ms, p_sliding_interval)
| extend in_range_window = bin(to_timestamp, p_sliding_interval) - ceil_from_timestamp
| where in_range_window >= p_window;
group_boundries
| join kind=inner row_level on in_range_group_id
| where out_of_range_record_flag == 0
| project Timestamp, Speed, Temperature
Timestamp Speed Temperature
2022-01-01T00:03:00Z 134.8 25.6
2022-01-01T00:04:00Z 125.3 25.5
2022-01-01T00:05:00Z 118.4 25.4
2022-01-01T00:06:00Z 106.3 26.3
2022-01-01T00:07:00Z 119.6 26.5
2022-01-01T00:08:00Z 134.7 25.4
2022-01-01T00:10:00Z 137.5 25.5
2022-01-01T00:11:00Z 129.9 27.4
2022-01-01T00:12:00Z 118.1 26.3
2022-01-01T00:13:00Z 105.4 25.7
2022-01-01T00:14:00Z 101.7 24.4
2022-01-01T00:15:00Z 100.8 25.6

Fiddle