2011-07-04 29 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的使用按行主要的順序,所以你必須明確地創建一個列。如:

>> 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);秒。重塑(5,1)[3,0] = 99; repr(s)' - >''數組([0,1,2,99,4])''。所以你可以做'A * B.reshape(5,1)'而不改變'B'。 – senderle

1

你有沒有嘗試過這樣的:

product = A * S 
+0

+1,使用numpy的廣播功能總是要走的路。 – lafras

+0

@ Stiefel,@MRAB,我認爲問題在於你必須爲[廣播工作]重塑'S'(http://stackoverflow.com/questions/6573166/python-numpy-multiplicate-tuple-by-scalar/6573533#6573533)。 – senderle

+0

對,由於形狀不匹配,A * S不起作用。重塑的確是解決方案。 – Stiefel

-1

我能想到的:

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

更快的解決方案可能是:

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

雖然這並不讓你一個numpy的數組作爲輸出,並進行轉置。因此,要獲得類似的numpy的陣列(注意,這是不是第一個解決方案慢):

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

很可能有十多種有效的解決方案,包括比這更好的...

3

基本相同,@ senderle的回答,但不要求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

鋁強硬你的問題的標題稍有用詞不當,我想你所遇到的問題主要是相關的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) 

不過,現在一個簡單的方法,使S與廣播規則(的A* 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) 

無論如何,我個人更喜歡這種簡單無憂的方法:

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]]) 

因此與python;明確而不是隱含更直截了當。

+0

謝謝,我改變了標題。好答案。我接受了發件人的回答,因爲它是最簡單的。不知何故,所有答案都旨在將形狀修改爲(N,1)。 – Stiefel