2017-09-23 52 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) 

所以,很多的選擇矢量化等操作!