1

I have the following code:

def lfun(A):
    return np.where(A != 0, np.log(A), A)

B = np.array([[1,20,0],[10,0,20]])
C = lfun(B)
print(C)

The point is to take an array, calculate the log of the nonzero entries of the array, and leave the zero entries as simply zero (instead -inf or nan). When I run the code, it does what I want, however it also gives me a strange error:

"RuntimeWarning: divide by zero encountered in log"

Why is it dividing by zero?

  • @superbrain Which example you need? Copy the code and execute, you see the generated warning and the results.. Take a look [here](https://stackoverflow.com/questions/21610198/runtimewarning-divide-by-zero-encountered-in-log), for me this is the right explanation.. – Carlo Zanocco Aug 27 '20 at 16:13
  • 1
    @superbrain That's too minimal. The question is why `log(0)` is evaluated despite using `np.where(A != 0)`. – mkrieger1 Aug 27 '20 at 16:14
  • 1
    @superbrain it's not a far bigger example, you're being overly pedantic and missing the point. I don't think 4 extra entries in an array is making it hard for anyone to follow what I am asking. – mordecai iwazuki Aug 27 '20 at 16:15
  • @mkrieger1 But isn't that obvious? `np.where` gets to go when it's already too late, when `np.log(A)` has already run. – superb rain Aug 27 '20 at 16:15
  • @TSF My example has 9 characters. Yours has over 100. That's far bigger. – superb rain Aug 27 '20 at 16:18
  • 2
    @superbrain no, I believe it isn't obvious. You can see it happen, but you don't know why it is happening. No where in the [doc](https://numpy.org/doc/stable/reference/generated/numpy.where.html) is it explicitly mentioned that the operation is evaluated before the condition. Also, your example is NOT a minimal reproducible example. OP already knows that np.log(0) throws an error; he's asking why it's still occurring even though np.where is supposed to 'filter out' the zeros. – Mercury Aug 27 '20 at 16:19
  • 1
    But the question is not "why does log(0) divide by zero", but "why is log(0) evaluated when specifically trying to avoid it". – mkrieger1 Aug 27 '20 at 16:20
  • 1
    @superbrain your example demonstrates that you can't take log of 0 but nothing to do with the where function which is where the true problem lies. Anyways, it's clear now; the where function evaluates log before it does its magic. Thanks to the others for the help. – mordecai iwazuki Aug 27 '20 at 16:20
  • @TSF The answer that I found helped you? – Carlo Zanocco Aug 27 '20 at 16:21
  • 1
    @CarloZanocco yes, it solved my question thank you. – mordecai iwazuki Aug 27 '20 at 16:21
  • @Mercury Yes it's obvious, and yes I do know why it's happening. You're looking at the wrong doc. Look [here](https://docs.python.org/3/reference/expressions.html#calls) instead, which clearly says "All argument expressions are evaluated before the call is attempted". – superb rain Aug 27 '20 at 16:22
  • @TSF "the where function evaluates log" - No it doesn't. The log function evaluates the log. The where function only ever gets the result of that. – superb rain Aug 27 '20 at 16:25
  • @Mercury It isn't possible for the `numpy.where` function to do anything *other* than run on the result of `numpy.log`. The python interpreter sees any `func(other_func(x))` as "evaluate `other_func(x)`, then stick that into `func`". There's no way for `numpy.where` to "choose" not to evaluate the log first. – Davis Aug 27 '20 at 17:58

0 Answers0