# 在一维numpy数组中使用Numpy查找局部最大值/最小值

` `numpy.r_[True, a[1:] < a[:-1]] & numpy.r_[a[:-1] < a[1:], True]` `

` `import numpy as np from scipy.signal import argrelextrema x = np.random.random(12) # for local maxima argrelextrema(x, np.greater) # for local minima argrelextrema(x, np.less)` `

` `>>> x array([ 0.56660112, 0.76309473, 0.69597908, 0.38260156, 0.24346445, 0.56021785, 0.24109326, 0.41884061, 0.35461957, 0.54398472, 0.59572658, 0.92377974]) >>> argrelextrema(x, np.greater) (array([1, 5, 7]),) >>> argrelextrema(x, np.less) (array([4, 6, 8]),)` `

` `>>> x[argrelextrema(x, np.greater)[0]]` `

`scipy.signal`还分别提供`argrelmax``argrelmin`以查找最大值和最小值。

` `from numpy import * # example data with some peaks: x = linspace(0,4,1e3) data = .2*sin(10*x)+ exp(-abs(2-x)**2) # that's the line, you need: a = diff(sign(diff(data))).nonzero()[0] + 1 # local min+max b = (diff(sign(diff(data))) > 0).nonzero()[0] + 1 # local min c = (diff(sign(diff(data))) < 0).nonzero()[0] + 1 # local max # graphical output... from pylab import * plot(x,data) plot(x[b], data[b], "o", label="min") plot(x[c], data[c], "o", label="max") legend() show()` `

`+1`很重要，因为`diff`会减less原始索引号。

` `import numpy as np from matplotlib import pyplot a=np.array([10.3,2,0.9,4,5,6,7,34,2,5,25,3,-26,-20,-29],dtype=np.float) gradients=np.diff(a) print gradients maxima_num=0 minima_num=0 max_locations=[] min_locations=[] count=0 for i in gradients[:-1]: count+=1 if ((cmp(i,0)>0) & (cmp(gradients[count],0)<0) & (i != gradients[count])): maxima_num+=1 max_locations.append(count) if ((cmp(i,0)<0) & (cmp(gradients[count],0)>0) & (i != gradients[count])): minima_num+=1 min_locations.append(count) turning_points = {'maxima_number':maxima_num,'minima_number':minima_num,'maxima_locations':max_locations,'minima_locations':min_locations} print turning_points pyplot.plot(a) pyplot.show()` `

` `from scipy import signal import numpy as np #generate junk data (numpy 1D arr) xs = np.arange(0, np.pi, 0.05) data = np.sin(xs) # maxima : use builtin function to find (max) peaks max_peakind = signal.find_peaks_cwt(data, np.arange(1,10)) #generate an inverse numpy 1D arr (in order to find minima) inv_data = 1./data # minima : use builtin function fo find (min) peaks (use inversed data) min_peakind = signal.find_peaks_cwt(inv_data, np.arange(1,10)) #show results print "maxima", data[max_peakind] print "minima", data[min_peakind]` `

` `maxima [ 0.9995736] minima [ 0.09146464]` `

`ar = np.array([0,1,2,2,2,1,3,3,3,2,5,0])`

` `array([ 3, 7, 10], dtype=int64)` `

` `def findLocalMaxima(ar): # find local maxima of array, including centers of repeating elements maxInd = np.zeros_like(ar) peakVar = -np.inf i = -1 while i < len(ar)-1: #for i in range(len(ar)): i += 1 if peakVar < ar[i]: peakVar = ar[i] for j in range(i,len(ar)): if peakVar < ar[j]: break elif peakVar == ar[j]: continue elif peakVar > ar[j]: peakInd = i + np.floor(abs(ij)/2) maxInd[peakInd.astype(int)] = 1 i = j break peakVar = ar[i] maxInd = np.where(maxInd)[0] return maxInd` `
` `import numpy as np x=np.array([6,3,5,2,1,4,9,7,8]) y=np.array([2,1,3,5,3,9,8,10,7]) sortId=np.argsort(x) x=x[sortId] y=y[sortId] minm = np.array([]) maxm = np.array([]) i = 0 while i < length-1: if i < length - 1: while i < length-1 and y[i+1] >= y[i]: i+=1 if i != 0 and i < length-1: maxm = np.append(maxm,i) i+=1 if i < length - 1: while i < length-1 and y[i+1] <= y[i]: i+=1 if i < length-1: minm = np.append(minm,i) i+=1 print minm print maxm` `

`minm``maxm`包含最小值和最大值的指数。 对于一个庞大的数据集，它会给出很多极大值/极小值，所以在这种情况下先平滑曲线，然后应用这个algorithm。