我在尝试向下渲染以下凹凸函数时注意到一些奇怪的行为。它应该为打开间隔(-1,1)中的任何输入返回正值,并为其他地方的输入返回0:
>>import numpy as np
>>def bump(x):
if np.abs(x)<1:
return np.exp(-1/(1-x**2))
else:
return 0
>>vbump=np.vectorize(bump)
当我尝试在一个只包含(-1,1)中的值的数组上计算函数vbump
时,它的行为符合预期:
>>x=np.linspace(-0.99,0.99,10)
>>vbump(x)
array([ 1.50022600e-22, 8.57431637e-02, 2.38427081e-01,
3.25559999e-01, 3.63401061e-01, 3.63401061e-01,
3.25559999e-01, 2.38427081e-01, 8.57431637e-02,
1.50022600e-22])
另一方面,当我尝试在包含(-1,1)之外的值的数组上对它进行求值时,我得到全零,即使对于应该为正的值:
>>x2=np.linspace(-1.1,1.1,10)
>>vbump(x2)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
为什么会这样?我对python和numpy很新,但是根据我的理解,当我向量化一个函数时,它应该允许函数以元素方式跨越列表。为什么要在更大的阵列中影响其他地方的元素评估呢?
我应该补充一点,我已经找到了解决使用
评估数组上的凹凸函数的直接问题的解决方案>>np.piecewise(x, [x <=-1, x >= 1,(-1<x)&(x<1)], [0,0,lambda t:np.exp(-1/(1-t**2))])
但我仍然想了解我的初步方法发生了什么。
答案 0 :(得分:2)
正如np.vectorize
的文档所述:
vectorized
输出的数据类型是通过使用输入的第一个元素调用函数来确定的。通过指定otypes
参数可以避免这种情况。
当第一个值为-1.1时,函数的返回值为整数0,因此dtype变为整数dtype(具体取决于您的设置;对我而言,它是int32):< / p>
>>> vbump(np.array([-0.99]))
array([ 1.50022600e-22])
>>> vbump(np.array([-0.99])).dtype
dtype('float64')
>>> vbump(np.array([-1.0]))
array([0])
>>> vbump(np.array([-1.0])).dtype
dtype('int32')
将您的0
更改为0.0
(以便您总是返回浮点数),或指定otypes
:
>>> vbump = np.vectorize(bump, otypes=[float])
>>> vbump(np.linspace(-1.1, 1.1, 10))
array([ 0. , 0.02396887, 0.20269374, 0.31495442, 0.36234271,
0.36234271, 0.31495442, 0.20269374, 0.02396887, 0. ])