2014-09-30 21 views
4

我希望能夠快速實例化一個矩陣,其中一行中的前幾個(可變數量)單元爲0,其餘爲1。用x個零例示一個矩陣,其餘的例子

想象一下,我們需要一個3x4矩陣。

我已經先實例化的矩陣爲所有的人:

ones = np.ones([4,3]) 

然後想象我們有宣佈多少前導零有一個數組:

arr = np.array([2,1,3,0]) # first row has 2 zeroes, second row 1 zero, etc 

要求的結果:

array([[0, 0, 1], 
     [0, 1, 1], 
     [0, 0, 0], 
     [1, 1, 1]]) 

很明顯,這也可以以相反的方式完成,但我會考慮appr oach,其中1是默認值,零將被替換。

什麼是最好的方法來避免一些愚蠢的循環?

回答

6

這是一種方法。 n是結果中的列數。行數由len(arr)決定。

In [29]: n = 5 

In [30]: arr = np.array([1, 2, 3, 0, 3]) 

In [31]: (np.arange(n) >= arr[:, np.newaxis]).astype(int) 
Out[31]: 
array([[0, 1, 1, 1, 1], 
     [0, 0, 1, 1, 1], 
     [0, 0, 0, 1, 1], 
     [1, 1, 1, 1, 1], 
     [0, 0, 0, 1, 1]]) 

有兩個部分是如何工作的解釋。首先,如何創建一個與m零和n-m的行?爲此,我們使用np.arange創建具有值的行[0,1,...,N-1]`:

In [35]: n 
Out[35]: 5 

In [36]: np.arange(n) 
Out[36]: array([0, 1, 2, 3, 4]) 

接下來,該數組比較m

In [37]: m = 2 

In [38]: np.arange(n) >= m 
Out[38]: array([False, False, True, True, True], dtype=bool) 

那給出一組布爾值;第一個m的值爲False,其餘爲True。鑄造這些價值觀爲整數,我們得到的0和1組成的數組:

In [39]: (np.arange(n) >= m).astype(int) 
Out[39]: array([0, 0, 1, 1, 1]) 

要執行這種過度的陣列m值(你arr),我們使用broadcasting;這是解釋的第二個關鍵想法。

注什麼arr[:, np.newaxis]給出:

In [40]: arr 
Out[40]: array([1, 2, 3, 0, 3]) 

In [41]: arr[:, np.newaxis] 
Out[41]: 
array([[1], 
     [2], 
     [3], 
     [0], 
     [3]]) 

即,arr[:, np.newaxis]重塑arr成2 d陣列形狀(5,1)。 (arr.reshape(-1, 1)本來是用來代替。)現在,當我們比較這對np.arange(n)(1-d數組長度n),在廣播踢:

In [42]: np.arange(n) >= arr[:, np.newaxis] 
Out[42]: 
array([[False, True, True, True, True], 
     [False, False, True, True, True], 
     [False, False, False, True, True], 
     [ True, True, True, True, True], 
     [False, False, False, True, True]], dtype=bool) 

由於@RogerFan在他的評論中指出,這是基本參數的外積,使用>=操作。

最後投鍵入int給出期望的結果:

In [43]: (np.arange(n) >= arr[:, np.newaxis]).astype(int) 
Out[43]: 
array([[0, 1, 1, 1, 1], 
     [0, 0, 1, 1, 1], 
     [0, 0, 0, 1, 1], 
     [1, 1, 1, 1, 1], 
     [0, 0, 0, 1, 1]]) 
+0

爲什麼我沒有想到這個? ;-)感謝發佈。 (+1) – NPE 2014-09-30 21:38:28

+0

非常感謝!解釋可能對未來訪問者有用(儘管你現在可能只是在努力)。 – PascalVKooten 2014-09-30 21:39:48

+0

實際上,我沒有使用方矩陣;( – PascalVKooten 2014-09-30 21:44:48

1

不是因爲我想(我用mask_indices試驗),但是這也將做的工作是簡潔:

>>> n = 3 
>>> zeros = [2, 1, 3, 0] 
>>> numpy.array([[0] * zeros[i] + [1]*(n - zeros[i]) for i in range(len(zeros))]) 
array([[0, 0, 1], 
     [0, 1, 1], 
     [0, 0, 0], 
     [1, 1, 1]]) 
>>> 

工作原理非常簡單:連接多次所需的次數,一個元素列表[0][1],逐行創建數組。

+0

已更新的問題明確排除這個答案是有效的(我的錯誤),但可能仍然對其他人有用(沒有downvote) – PascalVKooten 2014-09-30 21:42:08

+0

@PascalvKooten是的,剛剛注意到,對不起,混淆了,但有一個更短的方法,只是給我一分鐘:) – BartoszKP 2014-09-30 21:44:05

+0

另外,請確保它也適用於非矩形矩陣。 – PascalVKooten 2014-09-30 21:45:30