Python - 扩展numpy数组会更改矢量化函数的所有值

时间:2016-04-03 15:59:12

标签: python arrays numpy vectorization

我在尝试向下渲染以下凹凸函数时注意到一些奇怪的行为。它应该为打开间隔(-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))])

但我仍然想了解我的初步方法发生了什么。

1 个答案:

答案 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.        ])