最近在学习一些关于Python的例子,主要是关于如何用列表作为参数输入三角函数中的例子,发现了一些奇怪而有趣的现象,先看例子:
例1:
#代码:
import numpy
import math
def func(x, p):
a, b, c=p
return a+b*(x+c)
x = numpy.linspace(0, 10, 50)
p=[1,2,3]
y = func(x,p)
print (y)
#结果:正常
例2:
#代码:
import numpy
import math
def func(x, p):
a, b, c=p
return a+b*math.sin(x+c)
x = numpy.linspace(0, 10, 50)
p=[1,2,3]
y = func(x,p)
print (y)
#结果:TypeError: only size-1 arrays can be converted to Python scalars
这里的例1是一个常规的可以计算出来的例子,而例2仅仅只是将例1中的函数a+b*(x+c)换成a+b*math.sin(x+c),运行却报错。这里先不解释,继续看例子。
例3:
#代码:
import numpy
import math
def func(x, p):
a, b, c=p
return a+b*numpy.sin(x+c)
x = numpy.linspace(0, 10, 50)
p=[1,2,3]
y = func(x,p)
print (y)
#结果:正常
对比例2和例3,唯一不同的地方就是例3将例2中的math.sin()换成了numpy.sin(),例3便能正常运行出来结果。我们注意到因为x=numpy.linspace(0,10,50),所以传入math.sin()和numpy.sin()函数中的参数x是一个列表。再结合例2报错的信息:only size-1 arrays can be converted to Python scalars,我们可以意识到一点:有可能程序默认的math.sin()是一个标量函数,所以不能传入列表为参数,而numpy.sin()是矢量函数,所以可以传入列表为参数。
为了验证上述想法,我们再看一个例子:
例4:
#代码:
import numpy
import math
def func(x, p):
a, b, c=p
return [a+b*math.sin(xi+c) for xi in x]
x = numpy.linspace(0, 10, 50)
p=[1,2,3]
y = func(x,p)
print (y)
#结果:和例3一致
考虑到math.sin()可能是我们猜想的标量函数,所以在例4中的return语句中,我们使用一个列表循环将列表x中的每个元素xi传入math.sin()中进行运算,可以发现是能正常运算的(显然,结果会和例3一致)。再一次证实了我们的猜想。以上,同样适用于其他的三角函数,有兴趣的可以验证。
可以进一步验证,同样的规律适用于numpy.exp()和math.exp()等类似的成对的函数。