【问题标题】:How to find the inflection point in a noisy curve?如何在嘈杂的曲线中找到拐点?
【发布时间】:2014-05-30 00:02:49
【问题描述】:

我有 numpy 二维数组定义的嘈杂曲线:

如您所见,它具有第一个平坦段,然后是上升、峰值和衰减阶段。我需要找到上升阶段的起点,这里用红点标记。我如何在 python 中做到这一点?

【问题讨论】:

  • 你能在一定距离上取y的平均值,得到与前一个值的差并使用第一个负值吗?
  • @Eyrofire,我已经考虑过了,但是这种方法对噪音非常敏感。我在此处显示的曲线相对平滑,但我可能需要处理几个数量级的信噪比较小的数据。
  • 看来您首先需要一个好的算法 - 平滑/过滤数据并仍然保留 拐点 点的最佳方法,您可能想在dsp.stackexchange.com 中询问.一旦你有了它,如果你需要,你可以带着你的 Python 实现返回这里。他们在那边是NumPySciPy aware
  • 您是否需要找到实际的拐点(即凹度变化的位置,向上或向下)?或者您是否试图确定信号强的频谱的起点?严格来说,红点不是拐点。
  • @Taro Sato,我需要起点。抱歉,即使是我的母语,我也不擅长数学术语。 ☺

标签: python numpy scipy signal-processing


【解决方案1】:

如果数据看起来像示例图中的数据,您可以估计背景及其噪声水平,并应用一些阈值来提取高于背景的数据部分。示例如下:

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import gaussian_filter


def generate_fake_data():
    """Generate data that looks like an example given."""
    xs = np.arange(0, 25, 0.05)
    ys = - 20 * 1./(1 + np.exp(-(xs - 5.)/0.3))
    m = xs > 7.
    ys[m] = -20.*np.exp(-(xs - 7.)[m] / 5.)

    # add noise
    ys += np.random.normal(0, 0.2, xs.size)
    return xs, ys


def main():
    xs, ys = generate_fake_data()

    # smooth out noise
    smoothed = gaussian_filter(ys, 3.)

    # find the point where the signal goes above the background noise
    # level (assumed to be zero here).
    base = 0.
    std = (ys[xs < 3] - base).std()
    m = smoothed < (base - 3. * std)
    x0 = xs[m][0]
    y0 = ys[m][0]

    plt.plot(xs, ys, '.')
    plt.plot(xs, smoothed, '-')
    plt.plot(x0, y0, 'o')
    plt.show()


if __name__ == '__main__':
    main()

【讨论】:

  • 嗯,这不准确,但很接近,谢谢。只是,高斯滤波器对上升动力学影响太大,我宁愿不使用任何滤波器。
  • 平滑在这里并不是真正必要的,但我只是用它来估计信号开始对数据贡献更多的位置。但是,如果您处理的数据比本示例中使用的更嘈杂,您可能需要某种方法来建模该转换;平滑只是一个快速的过程。
【解决方案2】:

好吧,我计算了小 dt 沿曲线的局部微分,并且导数曲线的极值很好地指出了“拐点”。我想,我会解决的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-13
    • 2013-10-06
    • 1970-01-01
    • 2016-06-24
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    相关资源
    最近更新 更多