0

I have a function that calculates some ratios between two large np.arrays (>1000L, >1000L):

def error(crm1, crm2):

    delta1 = np.zeros((crm1.shape[0], crm1.shape[1]))
    delta2 = np.zeros((crm2.shape[0], crm2.shape[1]))
    stt = np.int(crm1.shape[0])
    stp = np.int(crm1.shape[1])

    for m in xrange(stt):
        for n in xrange(stp):
            s1 = crm1[m, n]
            s2 = crm2[m, n]

            w1 = (min(s1, s2)**2)/s1
            w2 = (min(s1, s2)**2)/s2

        delta1[m, n] = w1
        delta2[m, n] = w2

    return (delta1, delta2)

Now I realised that I have to calculate this ratio between an variable amount of np.arrays (same dimension and data type) like:

# Case 1
error(array1, array2)

# Case 2
error(array1, array2, array3, array4)

# Case 3
error(array1, array2, array3, array4, array5, array6)

If it´s possible, I don´t want to write a code for each case because I have many function like the error() function. Is it possible to change the code with the result that the function works with an variable amount of np.arrays?

9
  • 3
    Possible duplicate of Can a variable number of arguments be passed to a function? Commented Oct 12, 2016 at 12:25
  • 2
    By the way you can do np.zeros_like(crm1) I think...it's simpler. Commented Oct 12, 2016 at 12:34
  • @JohnZwinck It would probably be safer to use np.zeros_like(crm1, dtype=np.float64), in case the caller passes in an array with an integer data type. Commented Oct 12, 2016 at 12:38
  • 1
    @petermailpan Why do you have +1 in for n in xrange(stp+1):? That will make the last value of n too big to be a second index of crm1 and result in an IndexError. Commented Oct 12, 2016 at 12:46
  • 1
    Also why not use delta1 = np.minimum(crm1, crm2)**2/crm1 (assuming crm2 has the same shape as crm1) instead of looping? it should be way faster. Commented Oct 12, 2016 at 13:17

1 Answer 1

1

You can use *args (the important thing is prefixing the argument name with *, you could call your argument *foo). You should also use numpy vectorization instead of looping through the array.

import numpy as np
def err(*args):
     # compute the pointwise min once and for all
     pointwise_min2 = np.minimum(*args)**2
     return tuple([pointwise_min2/arr for arr in args])

(if all the arrays have same shape, which I assumed since otherwise the calculation in your question makes no sense).

Sign up to request clarification or add additional context in comments.

2 Comments

Now I get it. It returns a tuple with all the ratios for the amount of *args and I am able to extract the individual ratios with indexing the tuple. Thank you all very much for your advices!
You can also unpack the tuple directly: delta1, delta2 = err(crm1, crm2)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.