Cómo obtener el índice de un elemento máximo en una matriz numpy a lo largo de un eje

118

Tengo una matriz NumPy bidimensional. Sé cómo obtener los valores máximos sobre ejes:

>>> a = array([[1,2,3],[4,3,1]])
>>> amax(a,axis=0)
array([4, 3, 3])

¿Cómo puedo obtener los índices de los elementos máximos? Entonces me gustaría como salidaarray([1,1,0])

Peter Smit
fuente

Respuestas:

142
>>> a.argmax(axis=0)

array([1, 1, 0])
eumiro
fuente
1
esto funciona bien para números enteros, pero ¿qué puedo hacer para los valores flotantes y los números entre 0 y 1
Priyom saha
100
>>> import numpy as np
>>> a = np.array([[1,2,3],[4,3,1]])
>>> i,j = np.unravel_index(a.argmax(), a.shape)
>>> a[i,j]
4
blaz
fuente
11
Note que esta respuesta es engañosa. Calcula el índice del elemento máximo de la matriz en todos los ejes, no a lo largo de un eje dado, como pregunta el OP: es incorrecto. Además, si hay más de un máximo, recupera los índices solo del primer máximo: esto debe señalarse. Intente a = np.array([[1,4,3],[4,3,1]])ver que regresa i,j==0,1y descuida la solución en i,j==1,0. Para los índices de todos los máximos utilice en su lugar i,j = where(a==a.max().
gg349
36

argmax()solo devolverá la primera aparición de cada fila. http://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html

Si alguna vez necesita hacer esto para una matriz con forma, esto funciona mejor que unravel:

import numpy as np
a = np.array([[1,2,3], [4,3,1]])  # Can be of any shape
indices = np.where(a == a.max())

También puede cambiar sus condiciones:

indices = np.where(a >= 1.5)

Lo anterior le brinda resultados en el formulario que solicitó. Alternativamente, puede convertir a una lista de coordenadas x, y mediante:

x_y_coords =  zip(indices[0], indices[1])
SevakPrime
fuente
2
Esto no funcionó para mí ... ¿Te refieres indices = np.where(a==a.max())a la línea 3?
atomh33ls
¡Tienes razón, atomh33ls! Gracias por ver eso. He arreglado esa declaración para incluir el segundo signo igual para el condicional adecuado.
SevakPrime
@SevakPrime, hubo un segundo error señalado por @ atomh33ls, en .max()lugar de .argmax(). Edite la respuesta
gg349
@ gg349, depende de lo que quieras. argmax lo proporciona a lo largo de un eje que parece ser la forma en que el OP quiere que haya aprobado esa respuesta por eumiro.
SevakPrime
Veo que la corrección @ atomh33ls y la que propongo conduce al índice de los elementos más grandes de la matriz, mientras que el OP preguntaba por los elementos más grandes a lo largo de un cierto eje. Sin embargo, tenga en cuenta que su solución actual conduce a x_y_coord = [(0, 2), (1, 1)]que NO coincide con la respuesta de @eumiro y es incorrecta. Por ejemplo, intente a = array([[7,8,9],[10,11,12]])ver que su código no tenga ningún impacto en esta entrada. También mencionas que esto funciona mejor que unravel, pero la solución publicada por @blas responde al problema del máximo absoluto, no solo a lo largo de un eje.
gg349
3
v = alli.max()
index = alli.argmax()
x, y = index/8, index%8
ahmed
fuente