2011-07-04 27 views
3

私は、形状(N、2)のnumpy配列Aと形状(N)のnumpy配列Sを持っています。numpyタプル配列にスカラー配列を掛ける方法

どのようにして両方のアレイを掛けますか?現在、私はこのコードを使用しています:

tupleS = numpy.zeros((N , 2)) 
tupleS[:,0] = S 
tupleS[:,1] = S 
product = A * tupleS 

私はpython初心者です。これを行うより良い方法はありますか?

答えて

6

numpyのは行優先を使用しています主な順序なので、明示的に列を作成する必要があります。以下のように:senderleの答え@と本質的に同じ

>> A = numpy.array(range(10)).reshape(5, 2) 
>>> B = numpy.array(range(5)) 
>>> B 
array([0, 1, 2, 3, 4]) 
>>> A * B 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: shape mismatch: objects cannot be broadcast to a single shape 
>>> B = B.reshape(5, 1) 
>>> B 
array([[0], 
     [1], 
     [2], 
     [3], 
     [4]]) 
>>> A * B 
array([[ 0, 0], 
     [ 2, 3], 
     [ 8, 10], 
     [18, 21], 
     [32, 36]]) 
+0

'reshape'はコピーではなく、ビューを作成することに注意してください。' >>> s = numpy.arange(5); s。reshape(5,1)[3,0] = 99; repr(s) ' - >' 'array([0、1、2、99、4])' 'となります。つまり、 'B * 'を変更せずに' A * B.reshape(5、1) 'を実行するだけです。 – senderle

1

あなたはこれを試してみました:速く解決策があるかもしれない

product = A * numpy.tile(S, (2,1)).T 

product = [d * S for d in A.T] 

それはあなたがnumpyのを取得しませんが

product = A * S 
+0

+1、numpyのブロードキャスト機能を使用すると、常に行く方法です。 – lafras

+0

@Stackel、@MRAB、問題は、あなたが[放送する]ために 'S'を作り直さなければならないと思います(http://stackoverflow.com/questions/6573166/python-numpy-multiplicate-tuple-by-scalar/6573533#6573533)。 – senderle

+0

右、形状の不一致によりA * Sが機能しません。実際には形状変更が解決策です。 – Stiefel

-1

を私が考えることができます配列を出力として、転置します。だから、同様のnumpyの配列(これは最初のソリューションよりも低速であることに注意)を取得するには:これらのより良いものを含めて十数他の有効な解決策は、おそらくあります

product = numpy.array([d * S for d in A.T]).T 

を...

3

が、Sのインプレース操作を必要としないあなたは、インデックスNoneこの意志と軸が追加された方法でスライス配列を取得することができます乗算:A * S[:,None]

>>> S = np.arange(5) 
>>> S 
array([0, 1, 2, 3, 4]) 
>>> A = np.arange(10).reshape((5,2)) 
>>> A 
array([[0, 1], 
     [2, 3], 
     [4, 5], 
     [6, 7], 
     [8, 9]]) 
>>> S[:,None] 
array([[0], 
     [1], 
     [2], 
     [3], 
     [4]]) 
>>> A * S[:,None] 
array([[ 0, 0], 
     [ 2, 3], 
     [ 8, 10], 
     [18, 21], 
     [32, 36]]) 
1

Alはあなたの質問のタイトルをタフには、私はあなたが直面している問題はnumpybroadcasting rulesに主に関連していると思いますが、少し誤った名称です。 (あなたがすでに認められてきたように)したがって、以下では動作しません。

In []: N= 5 
In []: A= rand(N, 2) 
In []: A.shape 
Out[]: (5, 2) 

In []: S= rand(N) 
In []: S.shape 
Out[]: (5,) 

In []: A* S 
------------------------------------------------------------ 
Traceback (most recent call last): 
    File "<ipython console>", line 1, in <module> 
ValueError: operands could not be broadcast together with shapes (5,2) (5) 

しかし、今簡単な方法は、(A* Sの要素ごとの積の)放送のルールとS互換性を持たせるために、されるように、その大きさを拡大します:

In []: A* S[:, None] 
Out[]: 
array([[ 0.54216549, 0.04964989], 
     [ 0.41850647, 0.4197221 ], 
     [ 0.03790031, 0.76744563], 
     [ 0.29381325, 0.53480765], 
     [ 0.0646535 , 0.07367852]]) 

しかし、これは次のように、本当にexpand_dimsための構文砂糖以外の何ものでもありません:

とにかく
In []: expand_dims(S, 1).shape 
Out[]: (5, 1) 

pythonでこのように

In []: S= rand(N, 1) 
In []: S.shape 
Out[]: (5, 1) 

In []: A* S 
Out[]: 
array([[ 0.40421854, 0.03701712], 
     [ 0.63891595, 0.64077179], 
     [ 0.03117081, 0.63117954], 
     [ 0.24695035, 0.44950641], 
     [ 0.14191946, 0.16173008]]) 

;:私は個人的にはこの単純な手間のかからないアプローチを好みます明示的ではなく明示的であることが暗黙的です。

+0

ありがとう、私はタイトルを変更しました。いい答えだ。それが一番簡単なので、私は答えを受け入れた。すべての答えは何とか形を(N、1)に変更することを目指しています。 – Stiefel

関連する問題