[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