使用 numpy 广播计算序列的部分和
Using numpy broadcasting to compute the partial sum of a series
我必须计算以下总和,S
定义为:
我试过以下功能:
import numpy as np
a = np.array([0.4,2.6,3, 1.2, 3.4])
b = np.array([-5,7,2,1.1,1.8])
c = np.array([3.3,30,15,0.4,28])
t = np.linspace(0, np.pi, 600)
def S(t):
return np.sum([a[i]*np.cos(b[i]*t + c[i]) for i in range(5)], axis=0)
这很好用。但我想知道是否有纯 numpy 版本使用广播而不依赖 Python 的列表理解?
我试过:
def S(t):
return np.sum(a*np.cos(b*t + c), axis=0)
当我计算 S(t)
时,出现以下错误:
...
ValueError: operands could not be broadcast together with shapes (5,) (600,)
我怎样才能让它正常工作?
我想我通过向 a
、b
和 c
数组添加新轴找到了答案,如下所示:
def S(t):
return np.sum(a[:,None]*cos(b[:,None]*t + c[:,None]), axis=0)
或
def S(t):
return np.sum(a[:,np.newaxis]*cos(b[:,np.newaxis]*t + c[:,np.newaxis]), axis=0)
编辑:
正如 Michael 在评论中所建议的,更好的解决方案是向 t
添加一个新轴(请注意,在这种情况下,求和是在 axis=1
上进行的):
def S(t):
return np.sum(a*cos(b*t[:,None] + c), axis=1)
怎么做?
对于广播,您需要在您希望具有“复制”值的维度中。所以它是这样工作的:
import numpy as np
a = np.array([0.4,2.6,3, 1.2, 3.4])
b = np.array([-5,7,2,1.1,1.8])
c = np.array([3.3,30,15,0.4,28])
t = np.linspace(0, np.pi, 600).reshape(-1,1)
np.sum(a*np.cos(b*t+c), axis=1)
如何检查你是否做对了?
你可以做的一个巧妙的技巧是将 sympy.symbols
放入你的数组中并做同样的事情。然后你得到它为你计算的公式:
import sympy
a = np.array(sympy.symbols([f"a{i}" for i in range(5)]))
b = np.array(sympy.symbols([f"b{i}" for i in range(5)]))
c = np.array(sympy.symbols([f"c{i}" for i in range(5)]))
t = np.array(sympy.symbols([f"t{i}" for i in range(10)])).reshape(-1,1)
cos = np.vectorize(sympy.cos)
np.sum(a*cos(b*t+c), axis=1)
这给了你
array([a0*cos(b0*t0 + c0) + a1*cos(b1*t0 + c1) + a2*cos(b2*t0 + c2) + a3*cos(b3*t0 + c3) + a4*cos(b4*t0 + c4),
a0*cos(b0*t1 + c0) + a1*cos(b1*t1 + c1) + a2*cos(b2*t1 + c2) + a3*cos(b3*t1 + c3) + a4*cos(b4*t1 + c4),
a0*cos(b0*t2 + c0) + a1*cos(b1*t2 + c1) + a2*cos(b2*t2 + c2) + a3*cos(b3*t2 + c3) + a4*cos(b4*t2 + c4),
a0*cos(b0*t3 + c0) + a1*cos(b1*t3 + c1) + a2*cos(b2*t3 + c2) + a3*cos(b3*t3 + c3) + a4*cos(b4*t3 + c4),
a0*cos(b0*t4 + c0) + a1*cos(b1*t4 + c1) + a2*cos(b2*t4 + c2) + a3*cos(b3*t4 + c3) + a4*cos(b4*t4 + c4),
a0*cos(b0*t5 + c0) + a1*cos(b1*t5 + c1) + a2*cos(b2*t5 + c2) + a3*cos(b3*t5 + c3) + a4*cos(b4*t5 + c4),
a0*cos(b0*t6 + c0) + a1*cos(b1*t6 + c1) + a2*cos(b2*t6 + c2) + a3*cos(b3*t6 + c3) + a4*cos(b4*t6 + c4),
a0*cos(b0*t7 + c0) + a1*cos(b1*t7 + c1) + a2*cos(b2*t7 + c2) + a3*cos(b3*t7 + c3) + a4*cos(b4*t7 + c4),
a0*cos(b0*t8 + c0) + a1*cos(b1*t8 + c1) + a2*cos(b2*t8 + c2) + a3*cos(b3*t8 + c3) + a4*cos(b4*t8 + c4),
a0*cos(b0*t9 + c0) + a1*cos(b1*t9 + c1) + a2*cos(b2*t9 + c2) + a3*cos(b3*t9 + c3) + a4*cos(b4*t9 + c4)],
dtype=object)
请注意,这不适用于 numpy 的余弦,因为它仅适用于浮点数。但是
cos = np.vectorize(sympy.cos)
为您提供一个适用于数组元素的 sympys 余弦版本。
我必须计算以下总和,S
定义为:
我试过以下功能:
import numpy as np
a = np.array([0.4,2.6,3, 1.2, 3.4])
b = np.array([-5,7,2,1.1,1.8])
c = np.array([3.3,30,15,0.4,28])
t = np.linspace(0, np.pi, 600)
def S(t):
return np.sum([a[i]*np.cos(b[i]*t + c[i]) for i in range(5)], axis=0)
这很好用。但我想知道是否有纯 numpy 版本使用广播而不依赖 Python 的列表理解?
我试过:
def S(t):
return np.sum(a*np.cos(b*t + c), axis=0)
当我计算 S(t)
时,出现以下错误:
...
ValueError: operands could not be broadcast together with shapes (5,) (600,)
我怎样才能让它正常工作?
我想我通过向 a
、b
和 c
数组添加新轴找到了答案,如下所示:
def S(t):
return np.sum(a[:,None]*cos(b[:,None]*t + c[:,None]), axis=0)
或
def S(t):
return np.sum(a[:,np.newaxis]*cos(b[:,np.newaxis]*t + c[:,np.newaxis]), axis=0)
编辑:
正如 Michael 在评论中所建议的,更好的解决方案是向 t
添加一个新轴(请注意,在这种情况下,求和是在 axis=1
上进行的):
def S(t):
return np.sum(a*cos(b*t[:,None] + c), axis=1)
怎么做?
对于广播,您需要在您希望具有“复制”值的维度中。所以它是这样工作的:
import numpy as np
a = np.array([0.4,2.6,3, 1.2, 3.4])
b = np.array([-5,7,2,1.1,1.8])
c = np.array([3.3,30,15,0.4,28])
t = np.linspace(0, np.pi, 600).reshape(-1,1)
np.sum(a*np.cos(b*t+c), axis=1)
如何检查你是否做对了?
你可以做的一个巧妙的技巧是将 sympy.symbols
放入你的数组中并做同样的事情。然后你得到它为你计算的公式:
import sympy
a = np.array(sympy.symbols([f"a{i}" for i in range(5)]))
b = np.array(sympy.symbols([f"b{i}" for i in range(5)]))
c = np.array(sympy.symbols([f"c{i}" for i in range(5)]))
t = np.array(sympy.symbols([f"t{i}" for i in range(10)])).reshape(-1,1)
cos = np.vectorize(sympy.cos)
np.sum(a*cos(b*t+c), axis=1)
这给了你
array([a0*cos(b0*t0 + c0) + a1*cos(b1*t0 + c1) + a2*cos(b2*t0 + c2) + a3*cos(b3*t0 + c3) + a4*cos(b4*t0 + c4),
a0*cos(b0*t1 + c0) + a1*cos(b1*t1 + c1) + a2*cos(b2*t1 + c2) + a3*cos(b3*t1 + c3) + a4*cos(b4*t1 + c4),
a0*cos(b0*t2 + c0) + a1*cos(b1*t2 + c1) + a2*cos(b2*t2 + c2) + a3*cos(b3*t2 + c3) + a4*cos(b4*t2 + c4),
a0*cos(b0*t3 + c0) + a1*cos(b1*t3 + c1) + a2*cos(b2*t3 + c2) + a3*cos(b3*t3 + c3) + a4*cos(b4*t3 + c4),
a0*cos(b0*t4 + c0) + a1*cos(b1*t4 + c1) + a2*cos(b2*t4 + c2) + a3*cos(b3*t4 + c3) + a4*cos(b4*t4 + c4),
a0*cos(b0*t5 + c0) + a1*cos(b1*t5 + c1) + a2*cos(b2*t5 + c2) + a3*cos(b3*t5 + c3) + a4*cos(b4*t5 + c4),
a0*cos(b0*t6 + c0) + a1*cos(b1*t6 + c1) + a2*cos(b2*t6 + c2) + a3*cos(b3*t6 + c3) + a4*cos(b4*t6 + c4),
a0*cos(b0*t7 + c0) + a1*cos(b1*t7 + c1) + a2*cos(b2*t7 + c2) + a3*cos(b3*t7 + c3) + a4*cos(b4*t7 + c4),
a0*cos(b0*t8 + c0) + a1*cos(b1*t8 + c1) + a2*cos(b2*t8 + c2) + a3*cos(b3*t8 + c3) + a4*cos(b4*t8 + c4),
a0*cos(b0*t9 + c0) + a1*cos(b1*t9 + c1) + a2*cos(b2*t9 + c2) + a3*cos(b3*t9 + c3) + a4*cos(b4*t9 + c4)],
dtype=object)
请注意,这不适用于 numpy 的余弦,因为它仅适用于浮点数。但是
cos = np.vectorize(sympy.cos)
为您提供一个适用于数组元素的 sympys 余弦版本。