numpy: Efficiently avoid 0s when taking log(matrix)

前端 未结 7 661
陌清茗
陌清茗 2020-12-13 18:12
from numpy import *

m = array([[1,0],
           [2,3]])

I would like to compute the element-wise log2(m), but only in the places whe

7条回答
  •  长情又很酷
    2020-12-13 18:32

    Problem

    Questions: Feb 2014, May 2012

    For an array containing zeros or negatives we get the respective errors.

    y = np.log(x)
    # RuntimeWarning: divide by zero encountered in log
    # RuntimeWarning: invalid value encountered in log
    

    Solution

    markroxor suggests np.clip, in my example this creates a horizontal floor. gg349 and others use np.errstate and np.seterr, I think these are clunky and does not solve the problem. As a note np.complex doesn't work for zeros. user3315095 uses indexing p=0, and NumPy.log has this functionality built in, where/out. mdeff demonstrates this, but replaces the -inf with 0 which for me was insufficient, and doesn't solve for negatives.

    I suggest 0 and np.nan (or if needed np.NINF/-np.inf).

    y = np.log(x, where=0

    John Zwinck uses mask matrix np.ma.log this works but is computationally slower, try App:timeit.

    Example

    import numpy as np
    x = np.linspace(-10, 10, 300)
    
    # y = np.log(x)                         # Old
    y = np.log(x, where=0

    App:timeit

    Time Comparison for mask and where

    import numpy as np
    import time
    def timeit(fun, xs):
        t = time.time()
        for i in range(len(xs)):
            fun(xs[i])
        print(time.time() - t)
    
    xs = np.random.randint(-10,+10, (1000,10000))
    timeit(lambda x: np.ma.log(x).filled(np.nan), xs)
    timeit(lambda x: np.log(x, where=0

提交回复
热议问题