2017-01-25 90 views
-1

我試圖找出不使用np.repeat創建大尺寸的下列添加操作的好方法。如果使用np.repeat並且添加是最好的解決方案,請告訴我。無重複的Numpy廣播示例

我也對在這種情況下廣播正在做什麼感到困惑。基本上我有一個四維矩陣,我想在第一和第二索引添加一個二維矩陣,而和整個索引0和索引這樣做3.

這正常工作

a = np.arange(64).reshape((2,4,4,2)).astype(float) 
b = np.ones((2,2)) 
a[:, 0:2, 0:2, : ] += b 

這將引發錯誤。這樣做的好方法是什麼?

a[:, 0:3, 0:3, :] += np.ones((3,3)) 

這工作,但不是我要找做

c = np.arange(144).reshape(3,4,4,3).astype(float) 
c[:, 0:3, 0:3, :] += np.ones((3,3)) 
+0

「正常工作」代碼實際上並沒有按照您的想法進行操作。它看起來像是在工作,因爲'b'的所有元素都是相等的。 – user2357112

回答

3

你可以包括從一開始就空軸:你應該用

a[:, 0:3, 0:3, :] += np.ones((3,3,1)) # 1 broadcasts against any axis 

類似:

a[:, 0:2, 0:2, : ] += np.ones((2,2,1)) 

因爲你(也許在不經意間)廣播這些對第三和第四軸。我想你想讓它播放到第二和第三,對嗎?


你也可以隨時np.expand_dimsaxis=-1添加尺寸:

>>> np.expand_dims(np.ones((2, 2)), axis=-1).shape 
(2, 2, 1) 

Nonenp.newaxis切片(它們是等價的!):

>>> np.ones((2, 2))[None, :, :, np.newaxis].shape 
(1, 2, 2, 1) 

第一個None不是正確的廣播所必需的,但最後一個是!


在這種情況下,重要的是要提到以最後維度開始的numpy廣播。所以如果你有兩個數組,每個由最後一個開始的維必須具有相同的形狀,或者其中一個必須是1(如果一個是1,那麼它沿着這個軸廣播!)。這就是爲什麼a[:, 0:2, 0:2, : ]工作:

>>> a[:, 0:2, 0:2, : ].shape 
(2, 2, 2, 2) 
>>> b.shape 
(2, 2) 

所以最後一個維度是相等的(既2)和第二最後一個是相等的(既2)。然而,隨着:

>>> np.ones((2,2,1)).shape 
(2, 2, 1) 

最後一個是21這樣的np.ones((2,2,1))最後軸被廣播,而第二和第三尺寸是相等的(所有2),以便使用numpy的逐元素的操作那裏。

+2

我喜歡'[None,:,:,None]'因爲它清楚地表明我們在兩端擴展尺寸(甚至通過第一個None是自動的)。 – hpaulj

2

要對齊排列的軸以復加,我們需要在末尾插入一個新的軸,像這樣 -

a[:, 0:3, 0:3, :] += np.ones((3,3))[...,None] 

讓我們在這裏學習的形狀:

In [356]: a[:, 0:3, 0:3, :].shape 
Out[356]: (2, 3, 3, 2) 

In [357]: np.ones((3,3)).shape 
Out[357]: (3, 3) 

In [358]: np.ones((3,3))[...,None].shape 
Out[358]: (3, 3, 1) 


Input1 (a[:, 0:3, 0:3, :])  :  (2, 3, 3, 2) 
Input2 (np.ones((3,3))[...,None]) :  (3, 3, 1) 

請記住,廣播規則規定單身人士尺寸(尺寸爲lengths = 1)將與其他非單身人士尺寸的長度相匹配。此外,未列出的尺寸實際上默認長度爲1

所以,這是可以廣播的,現在就可以使用。


第2部分:爲什麼以下工作?

c = np.arange(144).reshape(3,4,4,3).astype(float) 
c[:, 0:3, 0:3, :] += np.ones((3,3)) 

研究再次形狀 -

In [363]: c[:, 0:3, 0:3, :].shape 
Out[363]: (3, 3, 3, 3) 

In [364]: np.ones((3,3)).shape 
Out[364]: (3, 3) 

Input1 (c[:, 0:3, 0:3, :]) :  (3, 3, 3, 3) 
Input2 (np.ones((3,3)))  :   (3, 3) 

再由broadcastable規則,這是好的怎麼回事,所以沒有錯誤,但結果不是所預期的。

+0

@MSeifert在那裏添加。 – Divakar

+0

謝謝,我真的很困惑了一會兒。 :) – MSeifert