MasterOn MasterOn - 1 month ago 8
Python Question

Dynamic call of a function

I have array that might be 3X3 or 5X3 or 7X3, let us assume the following array:

1 1.1 1
0.9 .8 0.99
0.9 0.7 0.7
1 1 1
0.7 .5 .9
0.9 0.95 0.8
1 1 1


In each row I want to find the maximum and if the maximum is the first element I want to call
function1
, if maximum is in 2nd place I want to call
function2
, and if maximum is in third place I want to call
function3.


The same procedure is repeated for each row.

How could I do this in python?

Answer

If you are using numpy, this becomes pretty simple with the use of np.argmax -- Here's a pretty straight forward script to help illustrate usage:

import numpy as np
arr = np.array([
    [1,    1.1,    1],
    [0.9,    .8,   0.99],
    [0.9,    0.7,    0.7],
    [1,    1,    1],
    [0.7,    .5,   .9],
    [0.9 ,   0.95,    0.8],
    [1,    1,    1]])


def func0(row):
    print(0, row)
def func1(row):
    print(1, row)
def func2(row):
    print(2, row)

funcs = [func0, func1, func2]
for ix, row in zip(np.argmax(arr, axis=1), arr):
    funcs[ix](row)

Note that argmax(arr, axis=1) will return an array whose values are 0, 1 or 2. Those values indicate the index in the row of the maximal value. We can zip the maximums with the array itself to get the index and the row at the same time. The only thing left to do is to map the indexes to the function to call and then call the function with the row as an input. I used a list, but you could just as easily use a dict.

If it's easier to avoid the zip, you can write it like this:

for row in arr:
    funcs[np.argmax(row)](row)

This way, you only do the processing 1 row at a time. This is similar to the solution posted by ShadowRanger, the use of argmax to pick out the maximal index allows the solution to be slightly more condensed (at the expense of a 3rd party import).