Home > Mobile >  RuntimeWarning: divide by zero encountered in log in masked arrays
RuntimeWarning: divide by zero encountered in log in masked arrays

Time:08-10

I've noticed that the RuntimeWarning: divide by zero encountered in log warnings gets triggered for masked arrays as well.

Consider the following two examples:

Regular arrays

>>> import numpy as np
>>> y = np.zeros((3,3))   np.eye(3,3)
>>> np.log(y)
<stdin>:1: RuntimeWarning: divide by zero encountered in log
array([[  0., -inf, -inf],
       [-inf,   0., -inf],
       [-inf, -inf,   0.]])

Masked arrays

>>> import numpy as np
>>> y = np.zeros((3,3))   np.eye(3,3)
>>> y_mask = np.ma.masked_equal(y, 0)
>>> np.log(y_mask)
<stdin>:1: RuntimeWarning: divide by zero encountered in log
masked_array(
  data=[[0.0, --, --],
        [--, 0.0, --],
        [--, --, 0.0]],
  mask=[[False,  True,  True],
        [ True, False,  True],
        [ True,  True, False]],
  fill_value=0.0)

Is this the expected behaviour? I would have expected the log operation to only happen on the non zero values in the case of masked arrays.

Additionally I have noticed that the this warning only gets triggered once per session. Any subsequent calls to the log function whether on masked or regular arrays won't trigger this warning.

I could suppress this warning via numpy.seterr(divide = 'ignore') but I'm curious as to why the operation on masked arrays raises a warning in the first place.

CodePudding user response:

np.ma versions of numpy functions can do one of several things.

  1. use compress to operate on just the unmasked values,

  2. use fill to replace masked elements with something like 1 or 0,

  3. use errstate to surpress the warnings. np.ma.log uses the surpress method

Source for np.ma.log is

Signature:       np.ma.log(a, *args, **kwargs)
Type:            _MaskedUnaryOperation
String form:     Masked version of <ufunc 'log'>
File:            /usr/local/lib/python3.8/dist-packages/numpy/ma/core.py
Source:         
class _MaskedUnaryOperation(_MaskedUFunc):
    """
    Defines masked version of unary operations, where invalid values are
    pre-masked.
    ...
    def __call__(self, a, *args, **kwargs):
    ...
         with np.errstate(divide='ignore', invalid='ignore'):
                result = self.f(d, *args, **kwargs)

Previously

Operations on numpy masked array gives invalid values masked

  • Related