2017-09-23 44 views
0

我有简单的函数,它看起来像这样:Python:如何重写函数以用于数组?

def summer_scalar(x): 
    a = np.array([1,2,3]) 
    b = np.array([7,8,9]) 
    return sum(a - b * x) 

它的工作原理,但如果我想与阵列使用它,例如numpy的阵列出现问题。如果我提交numpy的阵列我得到错误:

summer_scalar(np.array([7,8,9,7])) 
ValueError: operands could not be broadcast together with shapes (3,) (4,) 

我猜的原因是,它把我所有的数组作为同龄人,但他们都没有:从参数元素应处理一个一个后形成输出数组,应该像以前一样处理来自a和b的争论。所以它试图对不同大小的数组进行求和并失败。

我该怎么办?

我可以重写我的方法:

def summer(x): 
    a = np.array([1,2,3]) 
    b = np.array([7,8,9]) 
    s = 0 
    for ai,bi in zip(a,b): 
     s = s + ai - bi* x 
     #print ai,bi,s 
    return s 

这工作。

问题是:有没有更好的方法来修改我的矢量操作方法?

回答

1

是的,有更好的方法。

方法#1

直接了上述问题的一个量化的思维转换,使我们能够充分利用NumPy broacasting,像这样 -

(a-b*x[:,None]).sum(1) 

这是一个外部的产品,所以我们也可以使用NumPy的ufunc做同样的 -

(a-np.multiply.outer(x,b)).sum(1) 

方法2

仔细观察,似乎我们并不需要显式dimension-extension+broadcasting,我们可能只是总结的元素ab,做这样的事情 -

a.sum(0) - x*b.sum(0) 

我们能采用np.einsum我更换x*b.sum(0),像这样 -

a.sum(0) - np.einsum('i,j->i', x,b) 

再次,a.sum(0)合作ULD一个更einsum更换 -

np.einsum('i->',a) - np.einsum('i,j->i', x,b) 

所以,很多的选择矢量化等操作!