在Scipy中发现本地极端无法正常工作

时间:2019-06-28 18:04:59

标签: python scipy

我正在编写代码以查找类似于this stackoverflow问题的信号梯度的局部最小值和最大值。我正在使用argrelextrema来做到这一点。为了测试我的方法,我使用余弦函数进行了快速测试。

# Get the data
x = np.arange(start=0,
              stop=20,
              step=0.2)
y = np.cos(x)

# Calculate the gradient
gradient = []
for y1, y2 in zip(y, y[1:]):
    # Append the gradient (Delta Y / Delta X) where Delta X = 1
    gradient.append(y2-y1)

# Turn the gradient from a list to an array
gradient = np.array(gradient)

# Calculate the maximum points of the gradient
maxima = argrelextrema(gradient, np.greater_equal, order=2)
minima = argrelextrema(gradient, np.less_equal, order=2)

# Plot the original signal
plt.plot(x, y, label="Original Signal")
plt.scatter(x[maxima], y[maxima], color="red", label="Maxima")
plt.scatter(x[minima], y[minima], color="blue", label="Minima")
plt.title("Original Graph")
plt.legend(loc='lower left')
plt.show()

# Plot the gradient
plt.plot(gradient, label="First Derivative")
plt.scatter(maxima, gradient[maxima], color="red", label="Maxima")
plt.scatter(minima, gradient[minima], color="blue", label="Minima")
plt.title("1st Derivative Graph")
plt.legend(loc='lower left')
plt.show()

这将产生以下结果:

Local Minima and Maxima of a Cos graph

一切似乎都很好。但是,当我更改代码时:

x = [my data of 720 points]
y = [my data of 720 points some are np.inf]

Link to the data(另存为“ .txt”文件)

我得到的结果非常奇怪,如下所示:

Weird Minima and Maxima

起初,我认为可能是由于order=2函数的argrelextrema参数或信号中的噪声引起的。将order更改为较大的窗口大小会减少找到的点数,因此包括数字滤波器也是如此。但是,我仍然不明白为什么不能在梯度的峰值而不是简单地沿着平坦区域找到最大值和最小值?

注意: This question与我的问题相反。

编辑:

更改参数less_equallessgreater_equalgreater也会删除平坦区域上的许多点。尽管我仍然很困惑,为什么没有选择渐变的最大值和最小值。

1 个答案:

答案 0 :(得分:0)

问题已解决!

第一个问题是数据嘈杂。这意味着一直沿线找到最小值和最大值。您可以通过两种方式解决该问题。首先,您可以应用过滤器来平滑线条:

from scipy import ndimage

# Filter the signal (to remove excess noise)
scanner_readings = ndimage.gaussian_filter(data, sigma=3)

另一种选择是增加argrelextremaargrelextrema函数的窗口大小。

# Calculate the maximum points of the gradient
maxima = argrelextrema(gradient, np.greater_equal, order=4)
minima = argrelextrema(gradient, np.less_equal, order=4)

最后,似乎函数argrelextremaargrelextrema不能很好地处理不连续性。为了解决这个问题,我将所有inf值替换为找到的最大值,在这种情况下为10。您可以在下面查看如何执行此操作:

# Remove discontinuity (10 is the max value in the data)
data[data == np.inf] = 10

执行此操作时,将得到以下结果:

Original Signal First derivative