簡體   English   中英

numpy 數組的視圖和淺拷貝有什么區別?

[英]What's the difference between a view and a shallow copy of a numpy array?

在 NumPy 中,我知道切片數組會給你一個“視圖”,在我看來這與淺拷貝完全相同。 它們有何不同?

與包含對第一級元素對象(反過來可能會引用更深層次的對象)的引用的 Python 列表對象不同,NumPy 數組僅引用一個數據緩沖區,該緩沖區存儲數組所有維度的所有元素值,並且在此數據緩沖區之外沒有元素對象的層次結構。

列表的淺拷貝將包含第一級元素引用的副本,並與原始列表共享引用的元素對象。 一個 NumPy 數組的淺拷貝應該包含什么不太明顯。 它應該 ( A ) 與原始數據共享數據緩沖區,還是 ( B ) 擁有自己的副本(這有效地使其成為深層副本)?

NumPy 數組的視圖是 A 意義上的淺拷貝,即它引用與原始數據相同的數據緩沖區,因此對原始數據的更改會影響視圖數據,反之亦然。

庫函數copy.copy()應該創建其參數的淺拷貝,但是當應用於 NumPy 數組時,它會創建一個意義 B 的淺拷貝,即新數組獲得自己的數據緩沖區副本,因此更改一個陣列不影響另一個。

下面是一些代碼,展示了復制/查看 NumPy 數組的不同方式:

import numpy as np
import copy

x = np.array([10, 11, 12, 13])

# Create views of x (shallow copies sharing data) in 2 different ways
x_view1 = x.view()
x_view2 = x[:]          # Creates a view using a slice

# Create full copies of x (not sharing data) in 2 different ways
x_copy1 = x.copy()
x_copy2 = copy.copy(x)  # Calls x.__copy__() which creates a full copy of x

# Change some array elements to see what happens
x[0]       = 555        # Affects x, x_view1, and x_view2
x_view1[1] = 666        # Affects x, x_view1, and x_view2
x_view2[2] = 777        # Affects x, x_view1, and x_view2
x_copy1[0] = 888        # Affects only x_copy1
x_copy2[0] = 999        # Affects only x_copy2

print(x)                # [555 666 777  13]
print(x_view1)          # [555 666 777  13]
print(x_view2)          # [555 666 777  13]
print(x_copy1)          # [888  11  12  13]
print(x_copy2)          # [999  11  12  13]

上面的例子創建了整個原始數組索引范圍的視圖,並具有與原始數組相同的數組屬性,這不是很有趣(可以用簡單的別名替換,例如 x_alias = x)。 使視圖強大的原因在於它們可以是原始選定部分的視圖,並且具有不同的屬性。 這在擴展上述示例的接下來的幾行代碼中得到了演示:

x_view3 = x[::2].reshape(2,1) # Creates a reshaped view of every 2nd element of x
print(x_view3)          # [[555]
                        #  [777]]
x_view3[1] = 333        # Affects 2nd element of x_view3 and 3rd element of x
print(x)                # [555 666 333  13]
print(x_view3)          # [[555]
                        #  [333]]

基本上有兩種主要類型,一種是淺拷貝,第二種是深拷貝。

淺拷貝:在淺拷貝的情況下,如果您更改一個變量中的值,它將反映對另一個變量的更改。 例如 :

import numpy as np
a = np.array([1,2,3,4])
b=a
b[0]=353
print(b)
#>>> array([353,2,3,4])
print(a)
#>>> array([353,2,3,4])

深拷貝:如果深拷貝,如果您更改一個變量中的值,它不會反映對其他變量的更改。 例如 :

import numpy as np
a = np.array([1,2,3,4])
c=np.copy(a)
c[0]=111
print(c)
#>>> array([111,2,3,4])
print(a)
#>>> array([1,2,3,4])

暫無
暫無

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

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