B18_NumPy副本和视图(视图或浅拷贝、副本或深拷贝、深浅拷贝)
NumPy副本和視圖
副本是一個數據的完整的拷貝,如果我們對副本進行修改,它不會影響到原始數據,物理內存不在同一位置。
視圖是數據的一個別稱或引用,通過該別稱或引用亦便可訪問、操作原有數據,但原有數據不會產生拷貝。如果我們對視圖進行修改,它會影響到原始數據,物理內存在同一位置。
視圖一般發生在:
-
1、numpy的切片操作返回原數據的視圖。
-
2、調用ndarray的view()函數產生一個視圖。
副本一般發生在: -
Python序列的切片操作,調用deepCopy()函數。
-
調用ndarray的copy()函數產生一個副本。
無復制
簡單的賦值不會創建數組對象的副本。 相反,它使用原始數組的相同id()來訪問它。 id()返回 Python 對象的通用標識符,類似于 C 中的指針。
此外,一個數組的任何變化都反映在另一個數組上。 例如,一個數組的形狀改變也會改變另一個數組的形狀。
實例
輸出結果為:
我們的數組是: [0 1 2 3 4 5] 調用 id() 函數: 2160389265488 a 賦值給 b: [0 1 2 3 4 5] b 擁有相同 id(): 2160389265488 修改 b 的形狀: [[0 1][2 3][4 5]]視圖或淺拷貝
ndarray.view() 方會創建一個新的數組對象,該方法創建的新數組的維數更改不會更改原始數據的維數。
實例
輸出結果為:
數組 a: [[0 1][2 3][4 5]] 創建 a 的視圖: [[0 1][2 3][4 5]] 兩個數組的 id() 不同: a 的 id(): 2336918390944 b 的 id(): 2336918391184 b 的形狀: [[0 1 2][3 4 5]] a 的形狀: [[0 1][2 3][4 5]]使用切片創建視圖修改數據會影響到原始數組:
import numpy as nparr = np.arange(12) print('我們的數組:') print(arr) print('創建切片:') a = arr[3:] b = arr[3:] a[1] = 123 b[2] = 234 print(arr) print(id(a), id(b), id(arr[3:]))輸出結果為:
我們的數組: [ 0 1 2 3 4 5 6 7 8 9 10 11] 創建切片: [ 0 1 2 3 123 234 6 7 8 9 10 11] 2897481484528 2897481484448 2897481484688變量 a,b 都是 arr 的一部分視圖,對視圖的修改會直接反映到原數據中。但是我們觀察 a,b 的 id,他們是不同的,也就是說,視圖雖然指向原數據,但是他們和賦值引用還是有區別的。
副本或深拷貝
ndarray.copy() 函數創建一個副本。 對副本數據進行修改,不會影響到原始數據,它們物理內存不在同一位置。
import numpy as npa = np.array([[10, 10], [2, 3], [4, 5]]) print('數組 a:') print(a) print('創建 a 的深層副本:') b = a.copy() print('數組 b:') print(b) # b 與 a 不共享任何內容 print('我們能夠寫入 b 來寫入 a 嗎?') print(b is a) print('修改 b 的內容:') b[0, 0] = 100 print('修改后的數組 b:') print(b) print('a 保持不變:') print(a)輸出結果為:
數組 a: [[10 10][ 2 3][ 4 5]] 創建 a 的深層副本: 數組 b: [[10 10][ 2 3][ 4 5]] 我們能夠寫入 b 來寫入 a 嗎? False 修改 b 的內容: 修改后的數組 b: [[100 10][ 2 3][ 4 5]] a 保持不變: [[10 10][ 2 3][ 4 5]]深淺拷貝
在 Python 中,對象賦值實際上是對象的引用。當創建一個對象,然后把它賦給另一個變量的時候,Python 并沒有拷貝這個對象,而只是拷貝了這個對象的引用,我們稱之為淺拷貝。
在 Python 中,為了使當進行賦值操作時,兩個變量互補影響,可以使用 copy 模塊中的 deepcopy 方法,稱之為深拷貝。
append()函數
當 list 類型的對象進行 append 操作時,實際上追加的是該對象的引用。
id() 函數:返回對象的唯一標識,可以類比成該對象在內存中的地址。
如上例所示,當 num 發生變化時(前提是 id(num) 不發生變化),alist 的內容隨之會發生變化。往往會帶來意想不到的后果,想避免這種情況,可以采用深拷貝解決:
alist.append( copy.deepcopy( num ) )總結
以上是生活随笔為你收集整理的B18_NumPy副本和视图(视图或浅拷贝、副本或深拷贝、深浅拷贝)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云南人为什么爱吃米线?
- 下一篇: 什么炒菜的热量特别低?