Python 一维numpy阵列局部极大值的改进算法
我试图找到函数fx=sinx/x^2的局部极大值。 对于近似解,我初始化了两个变量x和y,并首先绘制了一个图形以获得直观表示Python 一维numpy阵列局部极大值的改进算法,python,arrays,algorithm,numpy,Python,Arrays,Algorithm,Numpy,我试图找到函数fx=sinx/x^2的局部极大值。 对于近似解,我初始化了两个变量x和y,并首先绘制了一个图形以获得直观表示 x = np.linspace(-20.0, 20.0, num=int((20+20)/0.01)) y = np.power(np.sin(x)/x, 2) plt.plot(x, y, 'r.', markersize= 1) plt.show() 这表明 然后我尝试创建一个算法来找到最大值: def returnMaxima(num, x, y):
x = np.linspace(-20.0, 20.0, num=int((20+20)/0.01))
y = np.power(np.sin(x)/x, 2)
plt.plot(x, y, 'r.', markersize= 1)
plt.show()
这表明
然后我尝试创建一个算法来找到最大值:
def returnMaxima(num, x, y):
"""
number, np.array, np.array -> list
num: number of maxima needed | x: x 1D array | y: y 1D array
returns [[x1,y1], [x2,y2]...] in descending order of y
"""
allMaximaPoints = [] # stores all Maxima points
reqMaximaPoints = [] # stores num Maxima points
for i in range(y.size):
# for first y value
if i == 0:
if y[i] > y[i+1]:
allMaximaPoints += [[x[i], y[i]], ]
# for last y value
elif i == y.size - 1:
if y[i] > y[i-1]:
allMaximaPoints += [[x[i], y[i]], ]
# for rest y values
else:
if y[i] > y[i-1] and y[i] > y[i+1]:
allMaximaPoints += [[x[i], y[i]], ]
# extract largest maximas from allMaximaPoints
while num > 0:
reqMaximaPoints += [max(allMaximaPoints, key=lambda item:item[1]),]
del allMaximaPoints[allMaximaPoints.index(max(allMaximaPoints, key=lambda item:item[1]))]
num -= 1
return reqMaximaPoints
当我尝试返回Maxima2,x,y时,我得到[[-4.4961240310077528,0.04719010162459622],
[4.4961240310077528,0.04719010162459622]]
这是不正确的,因为它跳过了x=0时的局部最大值。我怀疑这是因为在x=0时,与y[I]处的最大值相邻的y[I-1]和y[I+1]值大约等于导致该代码的y[I]
else:
if y[i] > y[i-1] and y[i] > y[i+1]:
allMaximaPoints += [[x[i], y[i]], ]
不要解释那一点。这是因为当我将dx=np.linspace-20.0,20.0,num=int20+20/0.01更改为x=np.linspace-20.0,20.0,num=int20+20/0.1,即x中的较大步长时,可以正确地找到x=0处的局部最大值。但是,即使我将上述代码中的>符号更改为>=,x=0处的最大值仍然不计算在内
为什么会这样?我应该如何改进代码以获得正确的结果?
谢谢 简单回答:x永远不是0,你可能也不希望它是0 我们可以通过运行
In [53]: 0 in x
Out[53]: False
这实际上是幸运的,因为x=0会导致运行时警告,并由于除以0而产生一个不是数字的nan值。问题是函数在0处未定义
否则,关于它为什么不起作用,您基本上是正确的。如果将>替换为>=您将看到输出不同:
In [55]: returnMaxima(2, x, y)
Out[55]:
[[-0.0050012503125778096, 0.99999166252624228],
[0.0050012503125778096, 0.99999166252624228]]
这实际上是正确的输出,因为这些是最大的值,并且是最接近于0的x值。您最好使用类似的方法。比如:
indices = scipy.signal.find_peaks_cwt(y, [1, 2, 3, 4], noise_perc=50)
plt.plot(x, y)
plt.plot(x[indices], y[indices], 'r.')
plt.show()
结果:
我为maxima找到的最好的库是peakutils:。它允许您选择灵敏度和阈值,使其对噪声具有鲁棒性。