1

So I have this simple function here

    def divide(arr):
        out = np.where(arr.any() <= 0, 0, 1/arr)
        return out

    a = np.array([0,1])
    print(divide(a))

When running this, the output is [inf 1.]. I thought that np.where() would replace the inf with 0, why is this not the case? How do I make it so that what is returned is [0,1]?

Edit:

So for the above, .any() should not be used. For this following function though, without using .any(), I get "ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()".

def entropy(x, n):
    return np.where(x.any() <= 0 or n<=0 , 0, -(x/n) * np.log2(x/n))

a = np.array([0,1])
n = 1

print((entropy(a,n)))
>> [nan -0.]

How do I resolve this issue?

  • 2
    Function arguments are evaluated before calling the function. So the function can't prevent an error in one of the arguments. – Barmar Apr 05 '23 at 23:32
  • Hmm ok that appears to work for this simple function let me update my question to my actual function. – redrobinyum Apr 05 '23 at 23:34
  • 1
    I guess this is different than the dupe target now. Your conditional should not only get rid of `.any()` but also switch to a bitwise `|` operator like `(x<=0) | (n<=0)`, but it still won't work due to @Barmar's explanation. – tdy Apr 05 '23 at 23:41
  • `x.any() <= 0` This is the wrong order to use `a.any()`. The intended way is to put .any() after the conditional. Example: `(x <= 0).any()` – Nick ODell Apr 05 '23 at 23:43
  • @NickODell That would be how to use `.any()`, but actually they shouldn't be using `.any()` here anyway (it doesn't make sense as an `np.where` conditional). – tdy Apr 05 '23 at 23:45
  • @tdy Seems like there should be a more general dup that addresses this. If you can find it, I'll replace my dupe. – Barmar Apr 05 '23 at 23:48
  • @Barmar Maybe this one? https://stackoverflow.com/a/60095295/13138364 – tdy Apr 05 '23 at 23:53
  • Since `np.where` is a function, it's arguments are evaluated first. Thus it can't suppress warnings in expressions like `1/a`. You can silence warnings. Or use a `where` parameter in a ufunc like `np.divide(1,a, where=a>0, out=np.zeros_like(a))`. – hpaulj Apr 06 '23 at 00:23
  • In the second expression the `np.log2` will require a similar `where/out` pair to avoid problems with `x/n==0`. Something like `-(x/n) * np.log2(x/n, where=x>0, out=np.zeros_like(x))` should work. The `x>0` is enough of a condition, since you want to skip individual elements of `x`, not the whole thing. Test scalar `n` separately. – hpaulj Apr 06 '23 at 00:31

0 Answers0