[SciPy-user] Finding local minima of greater than a given depth

Zachary Pincus zachary.pincus at yale.edu
Thu Aug 14 16:06:09 EDT 2008


> Is there a function within scipy somewhere which will, given an array
> representing values of a function, find all the local minima having a
> depth greater than some specified minimum?  The following works great
> for smooth functions, but when the data has noise in it, it also
> returns all of the (very) local minima, which I don't want.  The
> functions I'm working with are periodic (hence the modulo in the
> indices for endpoint cases).  Or, if there isn't such a built in
> functionality, what's the right way to measure the depth of a local
> minimum?

You could measure "depth" of minima (of a 1D array) by also finding  
the flanking maxima and looking at the distance between them. Or any  
of the other methods Rob suggested.

Another way to find local minima in a noise-robust manner that I've  
often seen is to not look for a minimum "depth", but for a minimum  
distance between minima. This is easy to implement using  
scipy.ndimage's minimum filter, which sets each element of an array to  
the minimum value seen over a specified neighborhood of that element.  
Then you just check for array elements where the element is equal to  
the minimum in the neighborhood...

I'd also suggest smoothing the data a bit with a gaussian to get rid  
or some of the noise. Scipy.ndimage also provides these filters.

Zach

PS. Here's my implementation... it returns the indices of the local  
maxima in a list. Also, the min-distance is in terms of manhattan  
distance, not euclidian, so be warned.

For a 2D array, the returned list will have two elements -- the row- 
indices of the maxima and the column-indices of the maxima. There's  
probably a better way to do that, but this is what I have.

def local_maxima(array, min_distance = 1, periodic=False,  
edges_allowed=True):
   """Find all local maxima of the array, separated by at least  
min_distance."""
   import scipy.ndimage as ndimage
   array = numpy.asarray(array)
   cval = 0
   if periodic:
     mode = 'wrap'
   elif edges_allowed:
     mode = 'nearest'
   else:
     mode = 'constant'
     cval = array.max()+1
   max_points = array == ndimage.maximum_filter(array,  
1+2*min_distance, mode=mode, cval=cval)
   return [indices[max_points] for indices in  
numpy.indices(array.shape)]




On Aug 14, 2008, at 3:40 PM, Zane Selvans wrote:

> Is there a function within scipy somewhere which will, given an array
> representing values of a function, find all the local minima having a
> depth greater than some specified minimum?  The following works great
> for smooth functions, but when the data has noise in it, it also
> returns all of the (very) local minima, which I don't want.  The
> functions I'm working with are periodic (hence the modulo in the
> indices for endpoint cases).  Or, if there isn't such a built in
> functionality, what's the right way to measure the depth of a local
> minimum?
>
> def local_minima(fitlist):
>     minima = []
>
>     for i in range(len(fitlist)):
>         if fitlist[i] < fitlist[mod(i+1,len(fitlist))] and fitlist[i]
> < fitlist[mod(i-1,len(fitlist))]:
>             minima.append(fitlist[i])
>
>     minima.sort()
>
>     good_indices = [ fitlist.index(fit) for fit in minima ]
>     good_fits = [ fit for fit in minima ]
>
>     return(good_indices, good_fits)
>
> --
> Zane Selvans
> Amateur Earthling
> http://zaneselvans.org
> zane at ideotrope.org
> 303/815-6866
> PGP Key: 55E0815F
>
> _______________________________________________
> SciPy-user mailing list
> SciPy-user at scipy.org
> http://projects.scipy.org/mailman/listinfo/scipy-user




More information about the SciPy-User mailing list