2017-09-23 9 views
0

私はそのようになります簡単な関数があります:それは動作しますが、私は例numpyのアレイのために、配列とそれを使用する場合の問題が表示されPython:配列で使用する関数を書き直すには?

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

を。私はnumpyの配列を提出した場合、私はエラーを取得する:

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

私は理由は、それがピアとしてすべての私の配列を扱いますが、そうでないということだと思います:引数の要素は、1の後に1つずつ処理し、出力アレイを形成する必要があります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) 

よく見ると210

方法#2

、我々がその明示的なdimension-extension+broadcastingを必要としないであろうと、私たちはただabの要素を合計し、このような何かを行うことができそうです -

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

我々可能性そのように、x*b.sum(0)を置き換えるために、ここでnp.einsumを採用 -

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

ここでも、a.sum(0)コ1以上einsumに置き換えることがULD - だから、

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

、オプションの多くは、このような操作をベクトル化します!

関連する問題