Mailing List Archive

How to find maximal entry in a Numpy array?
Hi. Is there a fast way to find the location of a maximal entry in a
Numeric array? I realize I could do something along the lines of
flattening it, finding the maximum value, and then searching for that
value, but that means going over the array twice. I could also use
argmax to find the position of the largest value in each column, make a
new array with dimension one less containing those maximal values, and
repeat, but I can't see how to make that new array without doing a
slow-looking python loop.

The best I've been able to come up with is to search in a python loop
over the entries specified by argmax. Is there a way to push more of
this down into C loops? And can someone please show me something better
than this horrendous "else: break" trick for iterating over the tuples
with entries less than some specific tuple?

import copy, Numeric

def find_max (array):
maximal_indices = argmax (array)
ashape = maximal_indices.shape
index = len (ashape) * [0]
maximal_value = 0
while 1:
if array [index + [maximal_indices [index]]] > \
maximal_value:
maximal_value = array [ \
index + [maximal_indices [index]]]
maximal_index = copy.copy (index)
for i in range (len (index)):
index [i] = index [i] + 1
if index [i] < ashape [i]: break
index [i] = 0
else: break
return maximal_index + [maximal_indices [index]]

In the end, I'm probably not going to be happy with just the maximal
value, either. If there's a fast way to get all the indices, sorted by
their values, that would be even better.

No-harm-in-asking'ly Alex.
How to find maximal entry in a Numpy array? [ In reply to ]
This can be used for all kind of indices.

HTH,
__Janko

##### cut here
def find_index(lin_index, sh):
"""
Translates flat indices to multidimensioanl indeces of an array
with shape sh
"""
sh = list(sh)
sh.reverse()
new_index = Numeric.zeros((len(lin_index), len(sh)))
mod = Numeric.zeros(len(lin_index))
for j in Numeric.arange(len(lin_index)):
count=len(sh)
for i in sh:
lin_index[j], mod[j] = divmod(lin_index[j], i)
count = count - 1
new_index[j, count] = mod[j]
return new_index

def find_max2(m):
"""Gives the indices of maximum value in m"""
return find_index([Numeric.argmax(m.flat)],m.shape)


--
Institut fuer Meereskunde phone: 49-431-597 3989
Dept. Theoretical Oceanography fax : 49-431-565876
Duesternbrooker Weg 20 email: jhauser@ifm.uni-kiel.de
24105 Kiel, Germany
How to find maximal entry in a Numpy array? [ In reply to ]
Thanks for your help, Janko.

Alex.
How to find maximal entry in a Numpy array? [ In reply to ]
Hi, again.

In case anyone else needs to do something like sorting an array and
keeping track of what belongs where in the array, I've found the
following function useful. It's not super-fast, but I guess it's doing
a lot.

import operator
from Numeric import *

def flatten_indices (array):
index_array = indices (array.shape)
index_list = map (ravel, tuple (index_array))
index_list = apply (map, (None, ) + tuple (index_list))
values = map (operator.getitem, \
len (index_list) * [array], \
index_list)
return map (None, values, index_list)

E.g.

>>> b = reshape (arange (4), (2, 2))
>>> flatten_indices (b)
[.(0, (0, 0)), (1, (0, 1)), (2, (1, 0)), (3, (1, 1))]
>>>

Alex.
How to find maximal entry in a Numpy array? [ In reply to ]
alex <alex@somewhere.around.here> writes:

> In the end, I'm probably not going to be happy with just the maximal
> value, either. If there's a fast way to get all the indices, sorted by
> their values, that would be even better.

And that's exactly what Numeric.argsort() returns!
--
-------------------------------------------------------------------------------
Konrad Hinsen | E-Mail: hinsen@cnrs-orleans.fr
Centre de Biophysique Moleculaire (CNRS) | Tel.: +33-2.38.25.55.69
Rue Charles Sadron | Fax: +33-2.38.63.15.17
45071 Orleans Cedex 2 | Deutsch/Esperanto/English/
France | Nederlands/Francais
-------------------------------------------------------------------------------
How to find maximal entry in a Numpy array? [ In reply to ]
Oh, cool. Thanks.

> And that's exactly what Numeric.argsort() returns!

Alex.