簡體   English   中英

為numpy數組賦值的花式索引

[英]Fancy indexing with assignment for numpy array

我有一個2維numpy數組:

A = np.zeros(16).reshape(4,4)

我希望(1, 1), (1,3), (3,1)(3,3)單元格的值為1。

A[[1,3], [1:3]] = 1 

僅指定1到(1,1)(3,3)

A[[1,3], :][:, [1, 3]] = 1

不起作用,因為它使數據的副本不是視圖。 這樣做的正確方法是什么?

使用步驟= 2的切片:

A[1::2,1::2] = 1

或者明確地傳遞所有索引:

A[[1,1,3,3],[1,3,1,3]] = 1

通常,當您使用數組以這種方式索引另一個數組時, numpy期望每個數組RC等具有相同的形狀。 例如,假設您要從此數組中提取非零值:

>>> a
array([[1, 3, 0, 0],
       [0, 0, 0, 0],
       [2, 4, 0, 0],
       [0, 0, 0, 0]])

您將創建一個行索引R數組:

>>> R
array([[0, 2],
       [0, 2]])

並且列索引C的數組:

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

並將它們傳遞進去:

>>> a[R, C]
array([[1, 2],
       [3, 4]])

請注意,這些可以是您喜歡的任何形狀 - 輸出將采用相同的形狀:

>>> RR
array([0, 2, 0, 2])
>>> CC
array([0, 0, 1, 1])
>>> a[RR, CC]
array([1, 2, 3, 4])

但是,如果您的索引數組中有重復,那么您可以通過使用廣播來省去一些麻煩。 唯一美中不足的是,所產生的數組必須播出 這意味着你需要明確地給它們額外的尺寸。 我將使用切片語法來保留額外的維度。

>>> r = R[0:1,:]
>>> c = C[:,0:1]
>>> r
array([[0, 2]])
>>> c
array([[0],
       [1]])
>>> a[r, c]
array([[1, 2],
       [3, 4]])

如果你沒有明確地給它們額外的尺寸, numpy會盡力理解你已經傳遞的東西,但它並不總是按預期工作。 更換0:1與片0刪除額外的維度:

>>> rr = r[0,:]
>>> cc = c[:,0]
>>> rr
array([0, 2])
>>> cc
array([0, 1])
>>> a[rr, c]
array([[1, 2],
       [3, 4]])
>>> a[r, cc]
array([[1, 4]])
>>> a[rr, cc]
array([1, 4])

第一個( a[rr, c] )是有效的,因為numpy可以從c的形狀告訴它應該廣播。 但另外兩個是模棱兩可的,所以numpy假設你並不意味着他們被廣播。

但是,請注意numpy還提供了使平面陣列可播放的快捷方式。 這可以派上用場!

>>> a[numpy.ix_(rr, cc)]
array([[1, 3],
       [2, 4]])
>>> A = np.zeros(16).reshape(4,4)
>>> A[[[1],[3]], [[1, 3]]] = 1
>>> A
array([[ 0.,  0.,  0.,  0.],
   [ 0.,  1.,  0.,  1.],
   [ 0.,  0.,  0.,  0.],
   [ 0.,  1.,  0.,  1.]])

這里發生的是行索引[[1],[3]]具有形狀(2,1),因此它們可以針對列索引[[1,3]]進行廣播,其具有形狀(1,2) ,導致行/列索引的形狀(2,2)數組。 因此,我們可以將上述內容視為以下簡稱:

>>> A[[[1, 1],[3, 3]], [[1, 3], [1, 3]]] = 1

這產生了相同的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM