首頁 > 軟體

Python中Numpy的深拷貝和淺拷貝

2022-05-24 22:04:09

1. 引言

深拷貝和淺拷貝是Python中重要的概念,本文重點介紹在NumPy中深拷貝和淺拷貝相關操作的定義和背後的原理。
閒話少說,我們直接開始吧!

2. 淺拷貝

2.1 問題引入

我們來舉個栗子,如下所示我們有兩個陣列a和b,樣例程式碼如下:

import numpy as np
a = np.array([1, 2, 3])
b = a
print('a =', a)
print('b =', b)

輸出如下:

a = [1 2 3]
b = [1 2 3]

此時如果我們對陣列a做如下改變,程式碼如下:

import numpy as np
a = np.array([1, 2, 3])
b = a
a [0] = 42
print('a =', a)
print('b =', b)

那麼我們的問題為: 此時b的值應該為多少?
執行上述程式碼後,我們得到輸出如下:

a = [42 2 3]
b = [42 2 3]

2.2 問題剖析

也許有人會覺得輸出應該為??a=[42 2 3]?? 和 ??b=[1 2 3]?? ,但是執行上述程式碼後我們發現??a??和??b??的值均發生了相應的改變。這主要是由於在??Numpy??中對變數的賦值操作,實際上發生的為淺拷貝。

換句話說,此時兩個變數指向同一塊記憶體地址,如下所示:

所以,此時如果我們修改陣列??original_array??中的某個元素,`copy_array

??由於和??original_array`公用同一塊記憶體,所以其中的元素也會發生相應的變化。

3. 深拷貝

3.1 舉個栗子

如果我們想要對??Numpy??陣列執行深拷貝,此時我們可以使用函數??copy()??。

相關的樣例程式碼如下:

import numpy as np
a = np.array([1, 2, 3])
b = a.copy()
print('a =', a)
print('b =', b)

輸出如下:

a = [1 2 3]
b = [1 2 3]

此時,如果我們改變陣列??a??中的元素,程式碼如下:

import numpy as np
a = np.array([1, 2, 3])
b = a.copy()
a [0] = 42
print('a =', a)
print('b =', b)

此時的程式碼輸出如下:

a = [42 2 3]
b = [1 2 3]

3.2 探究原因

觀察上述輸出,我們可以清楚地看到陣列??a??發生了改變而陣列??b??沒有發生變化,這是由於我們使用了深拷貝。

此時的記憶體地址如下:

由於 ??original_array??和??copy_array??指向不同的記憶體地址空間,所以此時我們對??original_array??的改變並不會對??copy_array??帶來影響。

4. 技巧總結

經過上述對深拷貝和淺拷貝的舉例和範例,相信大家都已有了清晰的認識,接著我們對上述知識點進行總結,歸納如下:

4.1 判斷是否指向同一記憶體

如果我們需要知道兩個變數是否指向同一塊記憶體地址,我們可以方便地使用??is??操作。

淺拷貝範例:

a = np.array([1, 2, 3])
b = a
print(b is a)

輸出如下:

True

深拷貝範例:

a = np.array([1, 2, 3])
b = a.copy()
print(b is a)

輸出如下:

False

4.2 其他資料型別

儘管本文中所有的範例都使用了NumPy陣列,但本文中所涉及的知識也適用於Python中的列表和字典等其他資料型別。
總之,我們需要時刻記載心中:在淺拷貝中,原始陣列和新的陣列共同執行同一塊記憶體;同時在深拷貝中,新的陣列是原始資料的單獨的拷貝,它指向一塊新的記憶體地址。

5. 總結

本文重點介紹了Python中對Numpy陣列操作的淺拷貝和深拷貝的概念和背後的原理,同時給出了相應的程式碼範例。

到此這篇關於Python中Numpy的深拷貝和淺拷貝的文章就介紹到這了,更多相關Python Numpy 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com