使用滑动时间检查值是否在阈值范围内 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 的温度。绘图部分很清楚,所以我只需要过滤行的帮助。
提前致谢!
这是一个对您的数据没有任何假设的解决方案。
其他信息,例如时间戳的粒度,可能有助于简化它。
- 将行分成组,将速度为 out-of-range (OOR) 的记录作为边界。还要添加一个合成记录,以后可以用作最小边界。
- 为每个组找到其边界,这些边界与滑动间隔 (1m) 对齐。这里的主要挑战是找到每个组的下边界,因为对于上边界,我们使用
bin
这是 floor 的同义词,但我们没有 ceiling 的等价物。
- 删除小于定义window(5m)的组。
- 将组边界与组记录连接起来并删除 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
我想在 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 的温度。绘图部分很清楚,所以我只需要过滤行的帮助。
提前致谢!
这是一个对您的数据没有任何假设的解决方案。
其他信息,例如时间戳的粒度,可能有助于简化它。
- 将行分成组,将速度为 out-of-range (OOR) 的记录作为边界。还要添加一个合成记录,以后可以用作最小边界。
- 为每个组找到其边界,这些边界与滑动间隔 (1m) 对齐。这里的主要挑战是找到每个组的下边界,因为对于上边界,我们使用
bin
这是 floor 的同义词,但我们没有 ceiling 的等价物。 - 删除小于定义window(5m)的组。
- 将组边界与组记录连接起来并删除 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 |