使用NumPy

时间:2017-02-28 18:21:18

标签: python arrays numpy

我在python中有一个函数,它可以在标量输入上运行,但在过程中乘以矩阵。确切的代码如下所示:

def f(t, n):
    T = np.pi
    a_0 = 0.5

    n = np.arange(1, n + 1)
    # Calculate the Fourier series of f(t)
    a_n = np.sin(n*T) / (n * np.pi)
    b_n = (1 - np.cos(n * T)) / (n * np.pi)
    res = a_0 + np.sum(a_n * np.cos(n*t)) + np.sum(b_n * np.sin(n*t))
    return res

现在,我希望这对输入t的向量进行操作,并使实现保持向量化(不用于循环)。我可以看到,制作一个维度len(t) x n的矩阵,其中初始向量n只是垂直叠加len(t)次,然后用t进行元素乘法将是一个解决方案,但是适当的是什么实现此功能的方式?

2 个答案:

答案 0 :(得分:1)

这是一个公式化的“矢量化”。请注意,只需要进行少量更改。第一行,最后一行。

第一行:asanyarray允许接受类似数组的输入,即标量,数组,嵌套列表等,并对它们进行相同的处理。索引在最后添加一个轴。这是傅里叶系数的空间。方便的是,这些将自动广播,因为它们占据最后一个尺寸,并且缺少轴插入左侧。这就是代码几乎没有变化的原因。

只有最后的总和必须限制在傅立叶轴上,这就是..., axis=-1) kwargs所做的。

def f(t, n):
    t = np.asanyarray(t)[..., None]
    T = np.pi
    a_0 = 0.5 
    n = np.arange(1, n + 1)
    # Calculate the Fourier series of f(t)
    a_n = np.sin(n*T) / (n * np.pi)
    b_n = (1 - np.cos(n * T)) / (n * np.pi)
    res = a_0 + np.sum(a_n * np.cos(n*t), axis=-1) + np.sum(b_n * np.sin(n*t), axis=-1)
    return res

答案 1 :(得分:1)

这是一种矢量化方法,使用broadcasting接受输入向量t,使用np.dot和最后一步使用{{3}} -

进行矩阵乘法
def f_vectorized(t, n): # where t is an array
    t2D = t[:,None]    

    T = np.pi
    a_0 = 0.5

    n = np.arange(1, n + 1)
    a_n = np.sin(n*T) / (n * np.pi)
    b_n = (1 - np.cos(n * T)) / (n * np.pi)

    nt2D = n*t2D
    return a_0 + np.cos(nt2D).dot(a_n) + np.sin(nt2D).dot(b_n)

示例运行 -

In [142]: t
Out[142]: array([8, 1, 8, 0, 2, 7, 8, 8])

In [143]: n = 5

In [144]: f_vectorized(t,n)
Out[144]: 
array([ 1.03254608,  0.94354963,  1.03254608,  0.5       ,  0.95031599,
        1.04127659,  1.03254608,  1.03254608])