我正在尝试定义一个函数log_bounded
,它与numpy的log
相同,用于正输入,但是它为非正输入提供了一个很大的负数。我需要它是一个可以接受数组作为输入的ufunc。
到目前为止,我有:
def log_bounded(x,verysmall=np.exp(-100)):
return np.log(np.maximum(x,verysmall))
这样可行,返回-100表示否定输入:
>>> log_bounded(2.72)
1.000631880307906
>>> log_bounded(-5)
-100.0
但我希望它返回一个更低的值,比如-10 ** 10。我认为理想的是检查x的值并直接返回低值,而不是记录接近于零的值,例如
def log_bounded_if(x, verylow=-10**10):
if x > 0:
return np.log(x)
else:
return verylow
但是,这个不能在数组上进行元素操作,因为if
试图为整个数组运行一次。
Scipy可以使用scipy.maximum(scipy.log(x),verylow)
完成工作,因为scipy.log
在非正输入上评估为负无穷大。但是,我需要使用numpy,因为这将与numba的autojit
一起运行,scipy似乎消除了速度优势。
答案 0 :(得分:0)
您可以通过logical indexing完成此操作。
最小解决方案:
import numpy as np
def log_bounded(x, verylow=-10**10):
y = np.log(x)
y[x <= 0] = verylow
return y
print log_bounded(np.arange(-2, 3))
输出:[ -1.00000000e+10 -1.00000000e+10 -1.00000000e+10 0 6.93147181e-01]
更高级的替代方案:(处理标量;保存不必要的log
次计算)
import numpy as np
def log_bounded(x, verylow=-10**10):
if np.isscalar(x): # handle scalars as well
if x > 0:
y = np.log(x)
else:
y = verylow
else:
y = np.empty_like(x)
y[x > 0] = np.log(x[x > 0]) # compute log only where needed
y[x <= 0] = verylow
return y
print log_bounded(-3), log_bounded(np.arange(-2, 3)), log_bounded(3)
输出:-10000000000 [-10000000000 -10000000000 -10000000000 0 0] 1.09861228867