今天在使用切片運算子修改陣列時,發現下面的操作得到了不同的結果,雖然操作看起來是一樣的。
import numpy as np
a = np.array([[1,2,3],[0,5,4],[4,5,3],[5,8,7]])
print(a)
a[[0,1],:][0:2,:] = [[11,12,13],[8,9,7]]
print(a)
a[0:2,:][[0,1],:] = [[11,12,13],[8,9,7]]
print(a)
結果如下:
[[1 2 3]
[0 5 4]
[4 5 3]
[5 8 7]]
[[1 2 3]
[0 5 4]
[4 5 3]
[5 8 7]]
[[11 12 13]
[8 9 7]
[4 5 3]
[5 8 7]]
我猜“a[[0,1],:]”會創建一個新陣列,而“a[0:2,:]”不會。但為什么?我很迷惑。我想知道在使用切片運算子時將在什么條件下創建新陣列。
uj5u.com熱心網友回復:
a[[0,1],:]帶有串列的是“高級索引”。它制作一個副本。這[0,1]不是切片。
a[0:2,:]切片是“基本索引”。它回傳一個view.
a[[0,1],:][0:2,:] = ...嘗試修改該副本,并且不會影響a. a[0:2,:][[0,1],:] = ...嘗試修改view,因此也修改了a。
a[[0,1],:] = ...將成功修改a。
在設定值時避免索引序列是一個好主意。 a[...][...] = .... 如本例所示,有時它有效,有時則無效。如果你完全避免它,你就不必擔心哪個有效。
即使在獲取值時,雙索引也不理想。它總是有效,但可能更難理解。
a[0:2,:][[0,1],:] = [[11,12,13],[8,9,7]]
被評估為
a.__getitem__((slice(0,2), slice(None))).
__setitem__(([0,1], slice(None)), [[11,12,13],[8,9,7] )
首先getitem執行 ,然后將setitem應用于該結果。因此,在鏈接索引時,了解第一個索引的作用至關重要。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/369824.html
