解决和平滑传感器数据中的噪声

Posted

技术标签:

【中文标题】解决和平滑传感器数据中的噪声【英文标题】:Address and smoothen noise in sensor data 【发布时间】:2022-01-17 18:18:27 【问题描述】:

我有如下传感器数据,其中在数据列下,在包含值 50 的前后行之间有 6 行包含值 45。要求是清理此数据并在 new_data 列中估算为 50(上一个值)。此外,噪声记录的数量(在表中显示为 45)可能在数量或行级别上有所不同。

案例1(样本数据):-

Sl.no Timestamp Data New_data
1 1/1/2021 0:00:00 50 50
2 1/1/2021 0:15:00 50 50
3 1/1/2021 0:30:00 50 50
4 1/1/2021 0:45:00 50 50
5 1/1/2021 1:00:00 50 50
6 1/1/2021 1:15:00 50 50
7 1/1/2021 1:30:00 50 50
8 1/1/2021 1:45:00 50 50
9 1/1/2021 2:00:00 50 50
10 1/1/2021 2:15:00 50 50
11 1/1/2021 2:30:00 45 50
12 1/1/2021 2:45:00 45 50
13 1/1/2021 3:00:00 45 50
14 1/1/2021 3:15:00 45 50
15 1/1/2021 3:30:00 45 50
16 1/1/2021 3:45:00 45 50
17 1/1/2021 4:00:00 50 50
18 1/1/2021 4:15:00 50 50
19 1/1/2021 4:30:00 50 50
20 1/1/2021 4:45:00 50 50
21 1/1/2021 5:00:00 50 50
22 1/1/2021 5:15:00 50 50
23 1/1/2021 5:30:00 50 50

我正在考虑需要将这些数据按时间戳 asc 排序(如下所示),然后可能有一个条件,它必须在大样本数据中逐组检查,如果第 1 组与组相同3 ,将组 2 替换为组 1 的值。

Sl.no Timestamp Data New_data group
1 1/1/2021 0:00:00 50 50 1
2 1/1/2021 0:15:00 50 50 1
3 1/1/2021 0:30:00 50 50 1
4 1/1/2021 0:45:00 50 50 1
5 1/1/2021 1:00:00 50 50 1
6 1/1/2021 1:15:00 50 50 1
7 1/1/2021 1:30:00 50 50 1
8 1/1/2021 1:45:00 50 50 1
9 1/1/2021 2:00:00 50 50 1
10 1/1/2021 2:15:00 50 50 1
11 1/1/2021 2:30:00 45 50 2
12 1/1/2021 2:45:00 45 50 2
13 1/1/2021 3:00:00 45 50 2
14 1/1/2021 3:15:00 45 50 2
15 1/1/2021 3:30:00 45 50 2
16 1/1/2021 3:45:00 45 50 2
17 1/1/2021 4:00:00 50 50 3
18 1/1/2021 4:15:00 50 50 3
19 1/1/2021 4:30:00 50 50 3
20 1/1/2021 4:45:00 50 50 3
21 1/1/2021 5:00:00 50 50 3
22 1/1/2021 5:15:00 50 50 3
23 1/1/2021 5:30:00 50 50 3

此外,还需要添加一个例外,例如,如果下一组具有相似的模式,则不要更改而是保留数据原样。 示例如下:如果第 1 组和第 3 组相同,则将第 2 组与第 1 组值估算。 但是如果第 2 组和第 4 组相同,则不要更改第 3 组,在 New_data 中保留相同的数据。

案例2:-

Sl.no Timestamp Data New_data group
1 1/1/2021 0:00:00 50 50 1
2 1/1/2021 0:15:00 50 50 1
3 1/1/2021 0:30:00 50 50 1
4 1/1/2021 0:45:00 50 50 1
5 1/1/2021 1:00:00 50 50 1
6 1/1/2021 1:15:00 50 50 1
7 1/1/2021 1:30:00 50 50 1
8 1/1/2021 1:45:00 50 50 1
9 1/1/2021 2:00:00 50 50 1
10 1/1/2021 2:15:00 50 50 1
11 1/1/2021 2:30:00 45 50 2
12 1/1/2021 2:45:00 45 50 2
13 1/1/2021 3:00:00 45 50 2
14 1/1/2021 3:15:00 45 50 2
15 1/1/2021 3:30:00 45 50 2
16 1/1/2021 3:45:00 45 50 2
17 1/1/2021 4:00:00 50 50 3
18 1/1/2021 4:15:00 50 50 3
19 1/1/2021 4:30:00 50 50 3
20 1/1/2021 4:45:00 50 50 3
21 1/1/2021 5:00:00 50 50 3
22 1/1/2021 5:15:00 50 50 3
23 1/1/2021 5:30:00 50 50 3
24 1/1/2021 5:45:00 45 45 4
25 1/1/2021 6:00:00 45 45 4
26 1/1/2021 6:15:00 45 45 4
27 1/1/2021 6:30:00 45 45 4
28 1/1/2021 6:45:00 45 45 4
29 1/1/2021 7:00:00 45 45 4
30 1/1/2021 7:15:00 45 45 4
31 1/1/2021 7:30:00 45 45 4

寻求帮助以使用 postgresql 进行编码以解决上述情况。请随时提出解决上述问题的任何替代方法。

【问题讨论】:

Redshift 还是 Postgres?这是两种截然不同的数据库产品 您不能“在 Redshift 中托管”。你要么使用 Postgres,要么使用 Redshift。 请考虑postgreSQL @a_horse_with_no_name Redshift 是数据库,使用 Postgresql 进行编码以从中获取数据。 【参考方案1】:

下面的查询应该可以满足需求。

    第一个查询标识对应于变化的行 数据。

    第二次查询对两次连续数据变化之间的行进行分组,并设置对应的时间戳范围

    第三个查询是一个递归查询,它在一个 按时间戳顺序迭代。

    最后一个查询显示预期的结果。

    WITH RECURSIVE list As
    (
    SELECT no
         , timestamp
         , lag(data) OVER w AS previous
         , data
         , lead(data) OVER w AS next
         , data IS DISTINCT FROM lag(data) OVER w AS first
         , data IS DISTINCT FROM lead(data) OVER w AS last
      FROM sensors
    WINDOW w AS (ORDER BY timestamp ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
    ), range_list AS
    (
    SELECT tsrange(timestamp, lead(timestamp) OVER w, '[]') AS range
         , previous
         , data
         , lead(next) OVER w AS next
         , first
      FROM list
     WHERE first OR last
    WINDOW w AS (ORDER BY timestamp ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
    ), rec_list (range, previous, data, next, new_data, arr) AS
    (
    SELECT range
         , previous
         , data
         , next
         , data
         , array[range]
      FROM range_list
     WHERE previous IS NULL
    UNION ALL
    SELECT c.range
         , p.data
         , c.data
         , c.next
         , CASE 
             WHEN p.new_data IS NOT DISTINCT FROM c.next
             THEN p.data
             ELSE c.data
           END
         , p.arr || c.range
      FROM rec_list AS p
     INNER JOIN range_list AS c
        ON lower(c.range) =  upper(p.range) + interval '15 minutes'
     WHERE NOT array[c.range] <@ p.arr
       AND first
     )
    SELECT s.*, r.new_data
      FROM sensors AS s
     INNER JOIN rec_list AS r
        ON r.range @> s.timestamp
     ORDER BY timestamp
    

    在dbfiddle查看测试结果

【讨论】:

以上是关于解决和平滑传感器数据中的噪声的主要内容,如果未能解决你的问题,请参考以下文章

过滤流数据以减少噪声,卡尔曼滤波器 c#

平滑来自传感器的数据

图像传感器sensor的噪声分析

传感器常用算法处理

简单实用!传感器3种常用算法处理(附代码)

技术科普 | 传感器3种常用算法处理(含代码)