2017-07-06 35 views
3

我試過如下:numpy的:通過引用傳遞不會對自身工作

p=np.array([[1,1,1],[2,2,2],[3,3,3]]) 
p[0,:] = p[1,:] 
y = p[1,:] 
print(p) 
p[1,1] = 4 
print(p) 
print(y) 

正如你可以看到輸出是:

[[2 2 2] 
[2 2 2] 
[3 3 3]] 
[[2 2 2] 
[2 4 2] 
[3 3 3]] 
[2 4 2] 

所以,當我分配的p第二行它是通過引用傳遞的。當我將p的第二行分配給第一行p時,它通過複製傳遞。爲什麼會這樣?

我期望的輸出是:

[[2 2 2] 
[2 2 2] 
[3 3 3]] 
[[2 4 2] 
[2 4 2] 
[3 3 3]] 
[2 4 2] 

回答

2

總之,差:

  • 訪問數組(... = p[])的切片創建一個新的視圖成如果可能的數據。
  • 指定給一個數組的片段(p[] = ...)將元素複製到數組中。

長的故事:

p = np.array([[1,1,1],[2,2,2],[3,3,3]])p保存原始數據。

y = p[1,:]給你一個視圖成p保存的數據(你可以在y.base通過查看驗證這一點,這是p)。這是不是數組的賦值,但是y是一個全新的對象,它與p共享數據。可以這樣想:

Data: [1, 1, 1, 2, 2, 2, 3, 3, 3] 
    ^ ^
     p  y 

數據只是一塊內存。 p指向這個內存的開始,並且y指向中間某處。 (它們不僅僅是「指向」,還包含關於維度和誰擁有數據的額外信息,但這並不重要)。

重要的是要認識到數組僅指向其關聯的開始數據。然後,它只需使用尺寸和步長(步幅)將數據解釋爲向量,矩陣等。請記住:一個數組 - 一個指針。

p[0,:] = p[1,:]這裏我們將p的一部分分配給數組的另一部分。爲了獲得預期的行爲,p的不同部分需要指向相同的數據塊。這是不可能的(但通過巧妙地操縱步幅可以通過有限的方式實現類似的事情)。相反,數據被複制。