我可能误解了广播如何在Python中运行,但我仍然遇到错误。
scipy
提供了许多特殊功能"它包含两个参数,特别是eval_XX(n, x[,out])
函数。
见http://docs.scipy.org/doc/scipy/reference/special.html
我的程序使用许多正交多项式,因此我必须在不同的点处评估这些多项式。我们来看具体的例子scipy.special.eval_hermite(n, x, out=None)
。
我希望x
参数为矩阵形(50, 50)
。然后,我想在多个点评估该矩阵的每个条目。我们将n
定义为一个numpy数组narr = np.arange(10)
(我们将numpy
导入为np
,即import numpy as np
)。
所以,请致电
scipy.special.eval_hermite(narr, matrix)
应返回Hermitian多项式H_0(matrix), H_1(matrix), H_2(matrix)
等。每个H_X(matrix)
的形状为(50,50)
,即原始输入矩阵的形状。
然后,我想总结这些价值观。所以,我打电话给
matrix1 = np.sum( [scipy.eval_hermite(narr, matrix)], axis=0 )
但是我收到广播错误!
ValueError: operands could not be broadcast together with shapes (10,) (50,50)
我可以用for循环解决这个问题,即
matrix2 = np.sum( [scipy.eval_hermite(i, matrix) for i in narr], axis=0)
这给了我正确的答案和输出matrix2.shape = (50,50)
。但是使用这个for循环减慢了我的代码,很长时间。请记住,我们正在使用矩阵条目。
有没有办法在没有for循环的情况下执行此操作?
答案 0 :(得分:1)
这些函数的文档很少,并且编译了很多代码,所以这只是基于实验:
special.eval_hermite(n, x, out=None)
n
显然是一个标量或整数数组。 x
可以是浮点数组。
special.eval_hermite(np.ones(5,int)[:,None],np.ones(6))
给了我(5,6)
个结果。这与我从np.ones(5,int)[:,None] * np.ones(6)
得到的形状相同。
np.ones(5,int)[:,None]
是一个(5,1)
数组,np.ones(6)
一个(6,)
,为此目的相当于(1,6)
。两者都可以扩展为(5,6)
。
我可以说,这些special
函数中的广播规则与*
等运算符相同。
由于special.eval_hermite(nar[:,None,None], x)
生成(10,50,50)
,您只需将sum
应用于其中的{0}即可生成(50,50)
。
special.eval_hermite(nar[:,Nar,Nar], x).sum(axis=0)
就像我之前写的那样,相同的广播(和求和)规则适用于此hermite
,就像*
这样的基本操作一样。
答案 1 :(得分:1)
eval_hermite
使用n
广播x
,然后在每个点评估H n (x)。因此,输出形状将是使用n
广播x
的结果。因此,如果您想要完成这项工作,则必须使n
和x
具有兼容的形状:
import scipy.special as ss
import numpy as np
matrix = np.ones([100,100]) # example
narr = np.arange(10) # example
ss.eval_hermite(narr[:,None,None], matrix).shape # => (10, 100, 100)
但请注意,这实际上可能更快:
out = np.zeros_like(matrix)
for n in narr:
out += ss.eval_hermite(n, matrix)
在测试中,它似乎比上述np.sum(...)
快5-10%。