Home > Mobile >  How to use argmin and argmax functions over a np.matrix element in python?
How to use argmin and argmax functions over a np.matrix element in python?

Time:08-30

I have the following situation. Let's define a D (8,4) matrix :

import numpy as np
import random

D=np.matrix([[72 22 58 63]
            [28 22 32 20]
            [40 41 58 20]
            [22 58 22 41]
            [28 78 51 45]
            [58 61 28 71]
            [51 22 28 51]
            [22 63 54 22]])

Let's set a random column:

j=np.random.choice(range(4))

We save this value in an empty list Sp.

Sp=[]
Sp.append(j)

I want to determinate the index of the maximum value in the matrix D over this column.

z=D[:,j].argmax(axis=0)

So far everything works fine. Now I want to do the same process but just for a subset of rows of the matrix D over the column j (for simplicity let's leave it fixed). I tried this

j=2                      #COLUMN.
a=[1,2,3,4]              #SUBSET OF ROWS TO CHECK.
z=D[a,j].argmax(axis=0)

The problem is that the index returned is not who corresponds to the element in the matrix D but the index in the matrix D[a,j]. The result should be z=2, which corresponds to the value 58, nonetheless, the value returned was z=1, which is the position of the value 58 but in the matrix D[a,j].

[[32]
 [58]
 [22]
 [51]]

I need the index with respect to the original matrix (D) when I do this process. Any idea? I have seen some approaches but I think should exist some easy way to do this?

Note that it is not the same as this question because the subset of rows is not always [1,2,3] or [5,6,7]. My example addresses a general subset, for example, [2,7,3,4] without a clear start - end.

CodePudding user response:

I can see that the matrix D declaration is wrong it should be import numpy as np import random

D=np.matrix([[72, 22, 58, 63],
             [28, 22, 32, 20],
             [40, 41, 58, 20],
             [22, 58, 22, 41],
             [28, 78, 51, 45],
             [58, 61, 28, 71],
             [51, 22, 28, 51],
             [22, 63, 54, 22]])

To use the argmax or argmin the correct way is

j=np.random.choice(range(4))
Sp=[]
Sp.append(j)

z = np.argmax(D[:,j], axis=0)
print(z)

This will print the require result you can refer enter link description here

CodePudding user response:

A little bit a workaround but it gets you the desired index in D:

j = 2
a = [1, 2, 3, 4]
z = D[a, j].max()

gives us the value of the maximum: 58

With this information we search for all values in D with 58, and make a new array with the indices of all maximum values:

arr = np.where(D == 58)
w = np.array(list(zip(*arr)))

which gets us:

array([[0, 2],
       [2, 2],
       [3, 1],
       [5, 0]], dtype=int64)

now we check with the possible indices from our range a, j with:

i = np.array(list(zip([j for _ in range(len(a))], a))) # array([[2, 1],
                                                       #        [2, 2],
                                                       #        [2, 3],
                                                       #        [2, 4]])
w[w == i]

the output is then:

array([2, 2], dtype=int64)

which is the index of the maximum value in D from D[a,j]


UPDATE with the suggested link by @Georgy link:

arr = np.where(D == 58)
arr[0][D[a,j].argmax()]

the output is then 2, if you just want the row index of your max value.

  • Related