【问题标题】:Filtering out noise from gpx data从 gpx 数据中滤除噪声
【发布时间】:2017-03-29 02:42:27
【问题描述】:

我有一个带有 speed 列的 Pandas 数据框,其中偶尔会出现噪音(数据来自 Garmin,表示运行期间捕获的数据)。

我试图找到一种方法来平均相邻点,但是当我遇到这样的事情时

9.112273445
164.5779550738
84.4553498412
4.231089359
4.3740439706

我陷入了无限循环。

我的算法比较幼稚:

# Get list of indices in which value is great than 6:
idx = z[(z['speed']>=6)].index
while list(idx) != []:
    for i in idx:
        # check if out of bounds
        if i + 1 >= len(z):
            z.iloc[i, z.columns.get_indexer(['speed'])] = (z['speed'].ix[i-2] + z['speed'].ix[i-1])/2
        elif i - 1 < 0:
            z.iloc[i, z.columns.get_indexer(['speed'])] = (z['speed'].ix[i+1] + z['speed'].ix[i+2])/2
        else:
            z.iloc[i, z.columns.get_indexer(['speed'])] = (z['speed'].ix[i-1] + z['speed'].ix[i+1])/2
    idx = z[(z['speed']>=6)].index

当然,问题是当我有两个非常大的相邻值时,这会陷入无限循环。

我正在应用这个过滤器(使用汉宁窗)来消除随机噪声:SciPy Cookbook SignalSmooth,但它没有处理数据中的这些大峰值。

除了丢弃它们,或者将它们设置为常数值,还有其他简单的方法来处理它们吗?

编辑

我正在测试的值是:

0           NaN
1      3.508394
2      5.097879
3      7.743824
4      9.138245
5     13.315918
6     12.836310
7     12.001393
8     15.815223
9      0.000000
10    16.622944
11     9.061864
12     2.089729
13     2.710874
Name: speed, dtype: float64

【问题讨论】:

    标签: python pandas scipy noise


    【解决方案1】:

    如果您想“桥接”大于 6 的值,您可以这样做:

    import numpy as np
    
    # locate outliers and adjacent values
    outliers = np.r_[False, (~np.isfinite(data)) | (data > 6), False]
    if np.any(outliers):
        boundaries = np.where(outliers[:-1] != outliers[1:])[0]
        lb = boundaries[::2]
        rb = boundaries[1::2]
        # special case if leftmost and/or rightmost values are outliers 
        lv = data[lb-1]
        if lb[0] == 0:
            lv[0] = data[rb[0]]
        rv = data[rb % len(data)]
        if rb[-1] == len(data):
            rv[-1] = data[lb[-1]-1]
        # create fill values; use a bit of trickery to keep it vectorised
        lengths = rb-lb
        fv = np.repeat((rv-lv)/(lengths+1), lengths)
        sw = np.cumsum(lengths[:-1])
        fv[sw] += fv[sw-1] - rv[:-1] + lv[1:]
        fv[0] += lv[0]
        fv = np.cumsum(fv)
        # place them
        out = data.copy()
        out[outliers[1:-1]] = fv
    else:
        out = data.copy()
    

    【讨论】:

    • fv = np.repeat((rv-lv)/(lengths+1), lengths) 遇到问题并抛出错误operands could not be broadcast together with shapes (3,) (2,) 值是:lengths -&gt; [6 2]rv-lv -&gt; 2 NaN, 9 0.0, 12 NaN(抱歉无法在 cmets 中将其格式化为 3x2 数组。)跨度>
    • 所以,看起来它正在尝试使用 1x2 数组广播 3x2。不确定 fv 代表什么。你能解释一下吗?
    • @horcle_buzz 嗯,也许是 nans。此外,rvlv 不应该是 2d。你能给我产生这个错误的输入吗?
    • @horcle_buzz fv 代表填充值,它包含所有用于替换异常值的线性插值。
    • @horcle_buzz 我已经更新了帖子,它现在可以处理 nans。但我不得不承认我从来没有使用过 pandas,所以我不知道这些行索引有什么用以及它们的行为方式。如果 data 是一维 numpy 数组,则代码应该可以工作。具有行索引的列是否表现得像一维数组?
    猜你喜欢
    • 1970-01-01
    • 2021-02-05
    • 2023-03-25
    • 2022-10-04
    • 1970-01-01
    • 2012-12-28
    • 2023-03-11
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多