NumPy副本和檢視


NumPy - 副本和檢視

在執行函式時,其中一些返回輸入陣列的副本,而另一些返回檢視。 當內容物理儲存在另一個位置時,稱為副本。 另一方面,如果提供了相同記憶體內容的不同檢視,我們將其稱為檢視

無複製

簡單的賦值不會建立陣列物件的副本。 相反,它使用原始陣列的相同id()來存取它。 id()返回 Python 物件的通用識別符號,類似於 C 中的指標。

此外,一個陣列的任何變化都反映在另一個陣列上。 例如,一個陣列的形狀改變也會改變另一個陣列的形狀。

範例

import numpy as np 
a = np.arange(6)  
print  '我們的陣列是:'  
print a 
print  '呼叫 id() 函式:'  
print id(a)  
print  'a 賦值給 b:' 
b = a 
print b 
print  'b 擁有相同 id():'  
print id(b)  
print  '修改 b 的形狀:' 
b.shape =  3,2  
print b 
print  'a 的形狀也修改了:'  
print a

輸出如下:

我們的陣列是:
[0 1 2 3 4 5]

呼叫 id() 函式:
139747815479536

a 賦值給 b:
[0 1 2 3 4 5]
b 擁有相同 id():
139747815479536

修改 b 的形狀:
[[0 1]
 [2 3]
 [4 5]]

a 的形狀也修改了:
[[0 1]
 [2 3]
 [4 5]]

檢視或淺複製

NumPy 擁有ndarray.view()方法,它是一個新的陣列物件,並可檢視原始陣列的相同資料。 與前一種情況不同,新陣列的維數更改不會更改原始資料的維數。

範例

import numpy as np 
# 最開始 a 是個 3X2 的陣列
a = np.arange(6).reshape(3,2)  
print  '陣列 a:'  
print a 
print  '建立 a 的檢視:' 
b = a.view()  
print b 
print  '兩個陣列的 id() 不同:'  
print  'a 的 id():'  
print id(a)  
print  'b 的 id():'  
print id(b)  
# 修改 b 的形狀,並不會修改 a
b.shape =  2,3  
print  'b 的形狀:'  
print b 
print  'a 的形狀:'  
print a

輸出如下:

陣列 a:
[[0 1]
 [2 3]
 [4 5]]

建立 a 的檢視:
[[0 1]
 [2 3]
 [4 5]]

兩個陣列的 id() 不同:
a 的 id():
140424307227264
b 的 id():
140424151696288

b 的形狀:
[[0 1 2]
 [3 4 5]]

a 的形狀:
[[0 1]
 [2 3]
 [4 5]]

陣列的切片也會建立檢視:

範例

import numpy as np 
a = np.array([[10,10],  [2,3],  [4,5]])  
print  '我們的陣列:'  
print a 
print  '建立切片:' 
s = a[:,  :2]  
print s

輸出如下:

我們的陣列:
[[10 10]
 [ 2 3]
 [ 4 5]]

建立切片:
[[10 10]
 [ 2 3]
 [ 4 5]]

深複製

ndarray.copy()函式建立一個深層副本。 它是陣列及其資料的完整副本,不與原始陣列共用。

範例

import numpy as np 
a = 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]]